SpaceMan
astrobasewiki
https://astrobase.miraheze.org/wiki/Main_Page
MediaWiki 1.40.1
first-letter
Media
Special
Talk
User
User talk
SpaceMan
SpaceMan talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
UserWiki
UserWiki talk
User profile
User profile talk
Video
Video talk
GeoJson
GeoJson talk
Campaign
Campaign talk
TimedText
TimedText talk
Module
Module talk
Topic
Navigation
Navigation talk
Module:Namespace detect
828
61
137
2014-04-05T17:01:23Z
Canopus >Mr. Stradivarius
0
use demopage instead of page as the main "page" parameter
Scribunto
text/plain
--[[
--------------------------------------------------------------------------------
-- --
-- NAMESPACE DETECT --
-- --
-- This module implements the {{namespace detect}} template in Lua, with a --
-- few improvements: all namespaces and all namespace aliases are supported, --
-- and namespace names are detected automatically for the local wiki. The --
-- module can also use the corresponding subject namespace value if it is --
-- used on a talk page. Parameter names can be configured for different wikis --
-- by altering the values in the "cfg" table in --
-- Module:Namespace detect/config. --
-- --
--------------------------------------------------------------------------------
--]]
local data = mw.loadData('Module:Namespace detect/data')
local argKeys = data.argKeys
local cfg = data.cfg
local mappings = data.mappings
local yesno = require('Module:Yesno')
local mArguments -- Lazily initialise Module:Arguments
local mTableTools -- Lazily initilalise Module:TableTools
local ustringLower = mw.ustring.lower
local p = {}
local function fetchValue(t1, t2)
-- Fetches a value from the table t1 for the first key in array t2 where
-- a non-nil value of t1 exists.
for i, key in ipairs(t2) do
local value = t1[key]
if value ~= nil then
return value
end
end
return nil
end
local function equalsArrayValue(t, value)
-- Returns true if value equals a value in the array t. Otherwise
-- returns false.
for i, arrayValue in ipairs(t) do
if value == arrayValue then
return true
end
end
return false
end
function p.getPageObject(page)
-- Get the page object, passing the function through pcall in case of
-- errors, e.g. being over the expensive function count limit.
if page then
local success, pageObject = pcall(mw.title.new, page)
if success then
return pageObject
else
return nil
end
else
return mw.title.getCurrentTitle()
end
end
-- Provided for backward compatibility with other modules
function p.getParamMappings()
return mappings
end
local function getNamespace(args)
-- This function gets the namespace name from the page object.
local page = fetchValue(args, argKeys.demopage)
if page == '' then
page = nil
end
local demospace = fetchValue(args, argKeys.demospace)
if demospace == '' then
demospace = nil
end
local subjectns = fetchValue(args, argKeys.subjectns)
local ret
if demospace then
-- Handle "demospace = main" properly.
if equalsArrayValue(argKeys.main, ustringLower(demospace)) then
ret = mw.site.namespaces[0].name
else
ret = demospace
end
else
local pageObject = p.getPageObject(page)
if pageObject then
if pageObject.isTalkPage then
-- Get the subject namespace if the option is set,
-- otherwise use "talk".
if yesno(subjectns) then
ret = mw.site.namespaces[pageObject.namespace].subject.name
else
ret = 'talk'
end
else
ret = pageObject.nsText
end
else
return nil -- return nil if the page object doesn't exist.
end
end
ret = ret:gsub('_', ' ')
return ustringLower(ret)
end
function p._main(args)
-- Check the parameters stored in the mappings table for any matches.
local namespace = getNamespace(args) or 'other' -- "other" avoids nil table keys
local params = mappings[namespace] or {}
local ret = fetchValue(args, params)
--[[
-- If there were no matches, return parameters for other namespaces.
-- This happens if there was no text specified for the namespace that
-- was detected or if the demospace parameter is not a valid
-- namespace. Note that the parameter for the detected namespace must be
-- completely absent for this to happen, not merely blank.
--]]
if ret == nil then
ret = fetchValue(args, argKeys.other)
end
return ret
end
function p.main(frame)
mArguments = require('Module:Arguments')
local args = mArguments.getArgs(frame, {removeBlanks = false})
local ret = p._main(args)
return ret or ''
end
function p.table(frame)
--[[
-- Create a wikitable of all subject namespace parameters, for
-- documentation purposes. The talk parameter is optional, in case it
-- needs to be excluded in the documentation.
--]]
-- Load modules and initialise variables.
mTableTools = require('Module:TableTools')
local namespaces = mw.site.namespaces
local cfg = data.cfg
local useTalk = type(frame) == 'table'
and type(frame.args) == 'table'
and yesno(frame.args.talk) -- Whether to use the talk parameter.
-- Get the header names.
local function checkValue(value, default)
if type(value) == 'string' then
return value
else
return default
end
end
local nsHeader = checkValue(cfg.wikitableNamespaceHeader, 'Namespace')
local aliasesHeader = checkValue(cfg.wikitableAliasesHeader, 'Aliases')
-- Put the namespaces in order.
local mappingsOrdered = {}
for nsname, params in pairs(mappings) do
if useTalk or nsname ~= 'talk' then
local nsid = namespaces[nsname].id
-- Add 1, as the array must start with 1; nsid 0 would be lost otherwise.
nsid = nsid + 1
mappingsOrdered[nsid] = params
end
end
mappingsOrdered = mTableTools.compressSparseArray(mappingsOrdered)
-- Build the table.
local ret = '{| class="wikitable"'
.. '\n|-'
.. '\n! ' .. nsHeader
.. '\n! ' .. aliasesHeader
for i, params in ipairs(mappingsOrdered) do
for j, param in ipairs(params) do
if j == 1 then
ret = ret .. '\n|-'
.. '\n| <code>' .. param .. '</code>'
.. '\n| '
elseif j == 2 then
ret = ret .. '<code>' .. param .. '</code>'
else
ret = ret .. ', <code>' .. param .. '</code>'
end
end
end
ret = ret .. '\n|-'
.. '\n|}'
return ret
end
return p
a4757000273064f151f0f22dc0e139092e5ff443
Template:Pagetype
10
58
131
2014-07-09T08:29:38Z
Canopus >Callanecc
0
Changed protection level of Template:Pagetype: [[WP:High-risk templates|Highly visible template]]: With more than 5.5 million transclusions and cascade protections this should be full protected as well ([Edit=Allow only administrators] (indefinite) [Move=
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:pagetype|main}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
b8e6aa66678cd57877ea2c607372a45070f030a7
Template:Str rep
10
69
153
2015-04-14T16:35:55Z
Canopus >Redrose64
0
Protected Template:Str rep: [[WP:High-risk templates|Highly visible template]]: 167176 transclusions ([Edit=Allow only template editors and admins] (indefinite) [Move=Allow only template editors and admins] (indefinite))
wikitext
text/x-wiki
{{#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|1}}<noinclude>
{{Documentation}}</noinclude>
4706daa3137857f2792cc7109ca24b6d58c78dee
Template:Comma separated entries
10
123
261
2015-05-26T18:05:33Z
Canopus >Izkala
0
Switch to using [[Module:Separated entries]]
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|comma}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
f9811ed089bab742e4aad8b8463eddcc7607f062
Module:IPAc-en/data
828
82
179
2015-06-19T11:38:13Z
Canopus >Mr. Stradivarius
0
switch to main data modules
Scribunto
text/plain
-- This module processes data for [[Module:IPAc-en]]. It is intended to be
-- loaded with mw.loadData.
local PRONUNCIATION_MODULE = 'Module:IPAc-en/pronunciation'
local PHONEME_MODULE = 'Module:IPAc-en/phonemes'
local function makeData(oldData)
local newData = {}
for i, old in ipairs(oldData) do
local new = {}
for k, v in pairs(old) do
if k ~= 'aliases' and k ~= 'code' then
new[k] = v
end
end
newData[old.code] = new
if old.aliases then
for i, alias in ipairs(old.aliases) do
newData[alias] = new
end
end
end
return newData
end
local function main()
local pronunciation = makeData(require(PRONUNCIATION_MODULE))
local phonemes = makeData(require(PHONEME_MODULE))
-- Check that no pronunciation keys are also contained in the phonemes
-- data. This would cause silent, hard-to-debug errors if it went
-- unchecked, so make it cause a big red error message instead.
for id in pairs(pronunciation) do
if phonemes[id] then
error(string.format(
"duplicate ID '%s' found in %s and %s",
id,
PRONUNCIATION_MODULE,
PHONEME_MODULE
))
end
end
return {
pronunciation = pronunciation,
phonemes = phonemes,
}
end
return main()
3428d5574793b97b1b5ba91ff0c32e0418c27642
Template:OED
10
133
281
2015-07-26T16:56:33Z
Canopus >PBS
0
PBS moved page [[Template:OED]] to [[Template:Cite OED]] over redirect: consistency with other similar templates such as [[template:cite ODNB]]
wikitext
text/x-wiki
#REDIRECT [[Template:Cite OED]]
{{R from move}}
d5391a8c7307b290008c46b310b929153eb9440f
Template:Cite journal
10
49
113
2015-11-13T02:17:24Z
Canopus >Fuhghettaboutit
0
Changed protection level of Template:Cite journal: when I changed this to add template editors, I didn't realize it had cascding protection—so all my change did was make it appear as if it could be edited by them ([Edit=Allow only administrators] (in...
wikitext
text/x-wiki
<includeonly>{{#invoke:Citation/CS1|citation
|CitationClass=journal
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
50b33a0bde8c0dc83f3753f7873bcb448b565944
Template:Cite encyclopedia
10
97
209
2015-11-13T02:17:24Z
Canopus >Fuhghettaboutit
0
Changed protection level of Template:Cite encyclopedia: when I changed this to add template editors, I didn't realize it had cascding protection—so all my change did was make it appear as if it could be edited by them ([Edit=Allow only administrators...
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=encyclopaedia
}}</includeonly><noinclude>
{{documentation}}
[[Category:Lua-based templates]]
</noinclude>
a5fbaa0493d06b11ef4dd711383f9fd5174a4238
Template:Cite conference
10
135
285
2015-11-13T02:17:24Z
Canopus >Fuhghettaboutit
0
Changed protection level of Template:Cite conference: when I changed this to add template editors, I didn't realize it had cascding protection—so all my change did was make it appear as if it could be edited by them ([Edit=Allow only administrators]...
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=conference
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
3c799319c67a4e713f07b5476ef62fa6a9efc608
Template:Nowrap
10
38
91
2015-11-28T10:13:53Z
Canopus >Edokter
0
Adapt comment; edits inside noinclude blocks should not affect job queue, but won't kill parser either way.
wikitext
text/x-wiki
<span class="nowrap">{{{1}}}</span><noinclude>
{{documentation}}
<!-- Categories go on the /doc page; interwikis go to Wikidata. -->
</noinclude>
5d0dc6b6d89b37f4356242404f46138a4017f015
Template:Cite web
10
85
185
2016-12-05T05:36:52Z
Canopus >Anthony Appleyard
0
Protected "[[Template:Cite web]]": restore old protection ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=web
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
ea1b0f38afd9728a1cf9f2e3f540887a402fab8e
Template:Portal bar
10
121
257
2016-12-10T22:05:10Z
Canopus >Renamed user mou89p43twvqcvm8ut9w3
0
Changed protection level for "[[Template:Portal bar]]": [[WP:High-risk templates|Highly visible template]] ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{#invoke:Portal bar|main}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
147fd2e53f15534b497d1049a4ea239049ec8fbc
Template:Zh
10
149
313
2017-04-27T14:29:36Z
Canopus >Anthony Appleyard
0
Anthony Appleyard moved page [[Template:Zh]] to [[Template:Lang-zh]]: [[Special:Permalink/777478128|Requested]] by Jc86035 at [[WP:RM/TR]]: Consistency with other similar templates such as {{[[Template:Lang-fr|Lang-fr]]}}.
wikitext
text/x-wiki
#REDIRECT [[Template:Lang-zh]]
{{R from move}}
6aa0af2f0918a28a55a7aa2f294fc53068c3b191
Template:IPAc-en
10
80
175
2017-06-22T21:12:36Z
Canopus >Nardog
0
<includeonly>
wikitext
text/x-wiki
<includeonly>{{#invoke:IPAc-en|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
f81b884979df2c3ec3a7275e7fb402ad585e26e4
Module:Gapnum
828
44
103
2017-10-10T17:39:00Z
Canopus >MusikAnimal
0
Changed protection level for "[[Module:Gapnum]]": [[WP:High-risk templates|High-risk Lua module]]: 7,000+ transclusions ([Edit=Require extended confirmed access] (indefinite))
Scribunto
text/plain
local p = {}
local getArgs
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = 'Template:Gapnum'})
local n = args[1]
if not n then
error('Parameter 1 is required')
elseif not tonumber(n) and not tonumber(n, 36) then -- Validates any number with base ≤ 36
error('Unable to convert "' .. args[1] .. '" to a number')
end
local gap = args.gap
local precision = tonumber(args.prec)
return p.gaps(n,{gap=gap,prec=precision})
end
-- Not named p._main so that it has a better function name when required by Module:Val
function p.gaps(n,tbl)
local nstr = tostring(n)
if not tbl then
tbl = {}
end
local gap = tbl.gap or '.25em'
local int_part, frac_part = p.groups(n,tbl.prec)
local ret = mw.html.create('span')
:css('white-space','nowrap')
-- No gap necessary on first group
:wikitext(table.remove(int_part,1))
-- Build int part
for _, v in ipairs(int_part) do
ret:tag('span')
:css('margin-left',gap)
:wikitext(v)
end
if frac_part then
-- The first group after the decimal shouldn't have a gap
ret:wikitext('.' .. table.remove(frac_part,1))
-- Build frac part
for _, v in ipairs(frac_part) do
ret:tag('span')
:css('margin-left',gap)
:wikitext(v)
end
end
return ret
end
-- Creates tables where each element is a different group of the number
function p.groups(num,precision)
local nstr = tostring(num)
if not precision then
precision = -1
end
local decimalloc = nstr:find('.', 1, true)
local int_part, frac_part
if decimalloc == nil then
int_part = nstr
else
int_part = nstr:sub(1, decimalloc-1)
frac_part = nstr:sub(decimalloc + 1)
end
-- only define ret_i as an empty table, let ret_d stay nil
local ret_i,ret_d = {}
-- Loop to handle most of the groupings; from right to left, so that if a group has less than 3 members, it will be the first group
while int_part:len() > 3 do
-- Insert in first spot, since we're moving backwards
table.insert(ret_i,1,int_part:sub(-3))
int_part = int_part:sub(1,-4)
end
-- handle any left over numbers
if int_part:len() > 0 then
table.insert(ret_i,1,int_part)
end
if precision ~= 0 and frac_part then
ret_d = {}
if precision == -1 then
precision = frac_part:len()
end
-- Reduce the length of the string if required precision is less than actual precision
-- OR
-- Increase it (by adding 0s) if the required precision is more than actual
local offset = precision - frac_part:len()
if offset < 0 then
frac_part = frac_part:sub(1,precision)
elseif offset > 0 then
frac_part = frac_part .. string.rep('0', offset)
end
-- Allow groups of 3 or 2 (3 first)
for v in string.gmatch(frac_part,'%d%d%d?') do
table.insert(ret_d,v)
end
-- Preference for groups of 4 instead of groups of 1 at the end
if #frac_part % 3 == 1 then
if frac_part:len() == 1 then
ret_d = {frac_part}
else
local last_g = ret_d[#ret_d] or ''
last_g = last_g..frac_part:sub(-1)
ret_d[#ret_d] = last_g
end
end
end
return ret_i,ret_d
end
return p
b855346e2e3abc47591f883503c6108f922f0849
Template:Cite book
10
96
207
2017-11-15T09:11:45Z
Canopus >Salix alba
0
put TD in a collapse top / bottom section
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=book
}}</includeonly><noinclude>
{{documentation}}
{{collapse top|TemplateData}}
{{Cite book/TemplateData}}
{{collapse bottom}}
</noinclude>
c474cbe5d051e08f516083d594207d449245c717
Template:DEC
10
138
291
2018-02-23T16:29:42Z
Canopus >Primefac
0
Changed protection level for "[[Template:DEC]]": [[WP:HIGHRISK|high-risk]] template with 4000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{Str rep|{{{1}}}|-|−}}°{{#ifeq: {{{2|+}}}|{{{2|-}}}| {{{2|}}}′|}}{{#ifeq: {{{3|+}}}|{{{3|-}}}| {{{3|}}}″|}}<noinclude>
{{documentation}}
</noinclude>
6927f28c38d0a50c1b2b56e84804d862ad50264a
Template:Starbox begin
10
153
321
2018-02-23T16:30:23Z
Canopus >Primefac
0
Changed protection level for "[[Template:Starbox begin]]": [[WP:HIGHRISK|high-risk]] template with 4000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{| class="infobox" style="width: 22em; font-size: 88%; <!-- text-align: left; --> line-height: 1.5em"
|+ style="font-size: 125%; font-weight: bold" | {{{name<includeonly>|{{PAGENAME}}</includeonly>}}}<noinclude>
|}{{Documentation}}</noinclude>
115f5bb26dd6bc3e6032bfe5080e62fffdb69a80
Template:Val
10
42
99
2018-02-23T16:30:35Z
Canopus >Primefac
0
Changed protection level for "[[Template:Val]]": [[WP:HIGHRISK|high-risk]] template with 4000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
<includeonly>{{{{{♥|safesubst:}}}#invoke:val|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
4765ec60d7235aeb2b778f12eac5cdcbd4ebab5d
Template:Engvar
10
142
299
2018-02-23T17:02:13Z
Canopus >Primefac
0
Changed protection level for "[[Template:Engvar]]": [[WP:HIGHRISK|high-risk]] template with 2000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{#invoke:Engvar|variants}}<noinclude>
{{documentation}}
</noinclude>
8a5e5d43fff0053bf6bd7fab7f761a6be4c05d21
Template:Solar luminosity
10
141
297
2018-02-23T17:02:56Z
Canopus >Primefac
0
Changed protection level for "[[Template:Solar luminosity]]": [[WP:HIGHRISK|high-risk]] template with 2000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar luminosity|<var>L</var><sub>☉</sub>]]
|<var>L</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
fb6372ee064d487f11d117a91d6ae84d9980f19f
Template:Solar mass
10
146
307
2018-02-23T17:02:56Z
Canopus >Primefac
0
Changed protection level for "[[Template:Solar mass]]": [[WP:HIGHRISK|high-risk]] template with 2000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar mass|<var>M</var><sub>☉</sub>]]
|<var>M</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
2a303d9d8a727c9f9ccc23508e1d17883808fbcc
Template:Solar radius
10
147
309
2018-02-23T17:02:56Z
Canopus >Primefac
0
Changed protection level for "[[Template:Solar radius]]": [[WP:HIGHRISK|high-risk]] template with 2000+ transclusions ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar radius|<var>R</var><sub>☉</sub>]]
|<var>R</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
12c29f2ba83c64dcc96a015a59244428c531f452
Template:Cite DR2
10
162
339
2018-12-07T16:26:19Z
Canopus >Lithopsian
0
Lithopsian moved page [[Template:Cite DR2]] to [[Template:Cite Gaia DR2]]: As discussed
wikitext
text/x-wiki
#REDIRECT [[Template:Cite Gaia DR2]]
{{R from move}}
f105cdaa4ffd5d7683d35297a855d5e4fc5c1c16
Module:Separated entries
828
74
163
2018-12-17T20:54:33Z
Canopus >Amorymeltzer
0
Changed protection level for "[[Module:Separated entries]]": [[WP:High-risk templates|High-risk Lua module]]: Over 2M transclusions ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux". The starting parameter can also be specified.
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard values before the starting parameter.
local start = tonumber(args.start)
if start then
for i = 1, start - 1 do args[i] = nil end
end
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction, first)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
args.first = first or args.first
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
e80231ff3de01afd7f62a94e0a34dc1e67504085
Module:Engvar
828
143
301
2019-02-25T04:25:52Z
Canopus >JJMC89
0
Changed protection level for "[[Module:Engvar]]": [[WP:High-risk templates|Highly visible module]]: match template ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
Scribunto
text/plain
-- This module implements Template:Engvar.
-- Template:Engvar is to be build into the template (like an infobox), with default & variant spellings defined.
-- That template should also allow parameter '|engvar=' for the editor (article page).
-- The module/template Engvar then returns the spelling variant as is set in that article (for example '|engvar=en-GB').
-- The defaultWord is returned, unless the engvar input hits on a defined (en-XX) variant word.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local gsub = string.gsub
local lower = string.lower
local upper = string.upper
function p.variants(frame)
local args = getArgs(frame)
return p._variants(args)
end
function p._variants(args)
local returnWord = nil
local defaultWord = args.defaultWord or ''
if args.engvar == nil then
-- Nothing to look for; use defaultWord right away
returnWord = defaultWord
elseif args.defaultLang == gsub(lower(args.engvar), '^en%-(%w%w)$', formatISO) then
-- By the defaultLang, the defaultWord is asked
returnWord = defaultWord
else
returnWord = args[gsub(lower(args.engvar), '^en%-(%w%w)$', formatISO)]
end
if returnWord == nil then
-- No hit so far. Search by words in the engvar entered, checking the list
local useLang = engvarLang(args.engvar)
if useLang == nil then
returnWord = defaultWord .. addMaintCat(args)
else
returnWord = args[useLang] or defaultWord
end
end
return returnWord
end
-- Returns arguments and intermediate result. Plus the template result, in front.
function p.explain(frame)
local args = getArgs(frame)
local ret = {}
table.insert(ret, '\n\n: Settings:')
table.insert(ret, 'defaultWord=' .. (args.defaultWord or '') .. '; ')
table.insert(ret, 'defaultLang=' .. (args.defaultLang or '') .. '; ')
table.insert(ret, 'engvarCat=' .. (args.engvarCat or '[default:yes]') .. '; ')
table.insert(ret, 'engvarCatSort=' .. (args.engvarCatSort or ''))
table.insert(ret, '\n\n: engvar=' .. (args.engvar or '') .. ' [input] ')
local useLang = engvarLang(args.engvar or '')
table.insert(ret, ' => Engvar code [used]: >' .. (useLang or '') .. '<.')
for k, v in pairs(args) do
if k == 'en-UK' then
table.insert(ret, k .. ' ? better: use "en-GB"; ')
elseif k == 'en-SA' then
table.insert(ret, k .. ' ? misleading; use "en-ZA"; ')
end
if k == 'defaultWord' then
elseif k == 'defaultLang' then
elseif k == 'engvar' then
elseif k == 'engvarcat' then
elseif k == gsub(lower(k), '^en%-(%w%w)$', formatISO) then
table.insert(ret, k .. '=' .. v .. '; ')
else
table.insert(ret, k .. ' [not standard:]=' .. v .. '; ')
end
end
return (args.engvar or '') .. ' => ' .. p._variants(args) .. table.concat(ret, ' ')
end
-- Turn a match into pattern 'en-XX'
function formatISO(country)
return ('en-' .. upper(country) or '')
end
function engvarLang(searchEngvar)
-- Search verbose language identifiers to ISO-format 'en-XX'
-- Assumed: not a blank string '' to search
local match = string.match
searchEngvar = gsub(searchEngvar, '^%s*en%-(.*)', '%1') -- rm any opening 'en-'.
searchEngvar = gsub(lower(searchEngvar), '[%s%(%)%-]', '') -- To lc, remove all: (, ) , ws, hyphen.
local useLang
--Special codes
if match(searchEngvar, 'oxford')
or searchEngvar == 'oed' then
useLang = 'en-OED' -- 'oxford' to catch before anyting 'british'
elseif match(searchEngvar, 'iupac') then
useLang = 'en-IUPAC' -- chemistry
-- Very often used
elseif match(searchEngvar, 'british')
or searchEngvar == 'uk'
or searchEngvar == 'gbr' then
useLang = 'en-GB'
elseif searchEngvar == 'us'
or match(searchEngvar, 'unitedstates')
or searchEngvar == 'american'
or searchEngvar == 'usa' then
useLang = 'en-US'
elseif match(searchEngvar, 'australia')
or searchEngvar == 'aus' then
useLang = 'en-AU'
-- Often used
elseif match(searchEngvar, 'india')
or searchEngvar == 'ind' then
useLang = 'en-IN'
elseif searchEngvar == 'newzealand'
or searchEngvar == 'nzl' then
useLang = 'en-NZ'
elseif match(searchEngvar, 'southafrica') -- not: en-SA
or searchEngvar == 'zaf' then
useLang = 'en-ZA'
elseif searchEngvar == 'canada'
or searchEngvar == 'can' then
useLang = 'en-CA'
elseif match(searchEngvar, 'hiberno')
or match(searchEngvar, 'ireland')
or match(searchEngvar, 'irish')
or searchEngvar == 'irl' then
useLang = 'en-EI'
elseif match(searchEngvar, 'hongkong')
or searchEngvar == 'hkg' then
useLang = 'en-HK'
-- Less often used
elseif match(searchEngvar, 'jamaica')
or searchEngvar == 'jam' then
useLang = 'en-JM'
elseif match(searchEngvar, 'malawi')
or searchEngvar == 'mwi' then
useLang = 'en-MW'
elseif match(searchEngvar, 'nigeria')
or searchEngvar == 'nga' then
useLang = 'en-NG'
elseif match(searchEngvar, 'pakistan')
or searchEngvar == 'pak' then
useLang = 'en-PK'
elseif match(searchEngvar, 'philippine')
or searchEngvar == 'phl' then
useLang = 'en-PH'
elseif match(searchEngvar, 'scotland')
or match(searchEngvar, 'scottish')
or searchEngvar == 'sco' then
useLang = 'en-SCO' -- Has no alpha-2 code; not 'scotch'
elseif match(searchEngvar, 'singapore')
or searchEngvar == 'sgp' then
useLang = 'en-SG'
elseif match(searchEngvar, 'trinidad')
or match(searchEngvar, 'tobago')
or searchEngvar == 'tto' then
useLang = 'en-TT'
else
useLang = nil
end
return useLang
end
function addMaintCat(args)
local catMaintenance
if args.engvarCat == 'no' then
else
local title = mw.title.getCurrentTitle()
if title:inNamespaces(0) then -- 0=main, 10=templ, 828=module
if args.engvarCatSort then
catMaintenance = '|' .. args.engvarCatSort .. ', ' .. title.text
end
catMaintenance = '[[Category:Articles using an unknown Template:Engvar option' .. (catMaintenance or '') .. ']]'
end
end
return catMaintenance or ''
end
return p
c67c97cf2bc643d26781b77fd4b0d63383ab47a8
Template:Cite dictionary
10
131
277
2019-03-05T14:21:58Z
Canopus >Xaosflux
0
Changed protection level for "[[Template:Cite dictionary]]": Pages alread protected from [[Wikipedia:Cascade-protected items/content]] ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
#REDIRECT [[Template:Cite encyclopedia]]
b08dc3862c41642a1bb23bc31b3764ffdce55dcc
Template:Rnd
10
145
305
2019-04-20T04:09:41Z
Canopus >Anthony Appleyard
0
Changed protection level for "[[Template:Rnd]]": asked ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
#REDIRECT [[Template:Round]]
60d43fe6637b72ea57395979124e0c4cea5b4f9e
Template:Citation
10
124
263
2019-05-06T17:38:52Z
Canopus >Trappist the monk
0
per [[Wikipedia:Templates for discussion/Log/2019 April 18#separate patent cites from Template:Citation|TfD]];
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=citation
}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
682134a60c143dec260ce779777d3be2d4c94eaa
Module:IPAc-en/pronunciation
828
83
181
2019-09-26T09:16:18Z
Canopus >Nardog
0
add "also" etc.
Scribunto
text/plain
-- This module contains pronunciation-key data for [[Module:IPAc-en]].
return {
{
code = 'lang',
text = 'English:'
},
{
code = 'pron',
text = ''
},
{
code = 'local',
text = 'locally'
},
{
code = 'ipa',
text = '[[International Phonetic Alphabet|IPA]]:'
},
{
code = 'also',
text = 'also'
},
{
code = 'uk',
text = '[[British English|UK]]:'
},
{
code = 'us',
text = '[[American English|US]]:'
},
{
code = 'uklang',
text = '[[British English]]:'
},
{
code = 'uslang',
text = '[[American English]]:'
},
{
code = 'ukalso',
text = '[[British English|UK]] also'
},
{
code = 'usalso',
text = '[[American English|US]] also'
},
{
code = 'alsouk',
text = 'also [[British English|UK]]:'
},
{
code = 'alsous',
text = 'also [[American English|US]]:'
},
}
f4b022e065c591350dd1ee03942c104a3a096395
Template:Lang-zh
10
148
311
2019-11-06T06:28:12Z
Canopus >DannyS712
0
module moved
wikitext
text/x-wiki
<includeonly>{{#invoke:Lang-zh|Zh}}</includeonly><noinclude>{{documentation}}</noinclude>
09d0f2945fa94b8947d29d2329101bd511d11d2d
Module:Arguments
828
40
95
2020-04-01T06:12:40Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/sandbox$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
3134ecce8429b810d445e29eae115e2ae4c36c53
Module:Category handler
828
75
165
2020-04-01T06:12:40Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Module:Category handler/config
828
77
169
2020-04-01T06:12:40Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Module:Category handler/data
828
76
167
2020-04-01T06:12:41Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Module:Category handler/shared
828
78
171
2020-04-01T06:12:41Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Module:Namespace detect/config
828
63
141
2020-04-01T06:12:44Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Module:Namespace detect/data
828
62
139
2020-04-01T06:12:45Z
Canopus >MusikAnimal
0
1 revision imported
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Module:Yesno
828
39
93
2020-04-01T06:27:55Z
Canopus >MusikAnimal
0
Undid revision 948472533 by [[Special:Contributions/w>Vogone|w>Vogone]] ([[User talk:w>Vogone|talk]])
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'on'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'off'
or tonumber(val) == 0
then
return false
else
return default
end
end
f767643e7d12126d020d88d662a3dd057817b9dc
Module:No globals
828
41
97
2020-04-01T06:28:55Z
Canopus >MusikAnimal
0
Undid revision 948472525 by [[Special:Contributions/w>DiBabelYurikBot|w>DiBabelYurikBot]] ([[User talk:w>DiBabelYurikBot|talk]])
Scribunto
text/plain
local mt = getmetatable(_G) or {}
function mt.__index (t, k)
if k ~= 'arg' then
error('Tried to read nil global ' .. tostring(k), 2)
end
return nil
end
function mt.__newindex(t, k, v)
if k ~= 'arg' then
error('Tried to write global ' .. tostring(k), 2)
end
rawset(t, k, v)
end
setmetatable(_G, mt)
8ce3969f7d53b08bd00dabe4cc9780bc6afd412a
Module:Category handler/blacklist
828
79
173
2020-04-18T08:48:05Z
Canopus >Jo-Jo Eumerus
0
Per category talk page
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template index/.*$',
-- Don't categorise archives.
'/[aA]rchive',
"^Wikipedia:Administrators' noticeboard/IncidentArchive%d+$",
}
87469d7a9ef2a3c41b2bf04ae18f7c59a18fb855
Module:Footnotes/anchor id list/data
828
104
223
2020-05-23T17:06:22Z
Canopus >Trappist the monk
0
Scribunto
text/plain
-- copied from Module:Ref info/data - maybe overkill here?
-- for this application make lists from the redirect lists and force all template names first character uppercase
require('Module:No globals');
--[[--------------------------< C S 1 _ T E M P L A T E _ P A T T E R N S >------------------------------------
These are patterns for cs1 templates and their redirects. These patterns exclude redirects that are vcite-like
which redirects should be deleted because vcite is not cs1.
]]
local cs1_template_patterns = { -- lua patterns of the cannonical names and redirects
'[Cc]ite ar[Xx]iv', -- arXiv is the canonical name
'[Cc]ite ArXiv',
'[Cc]ite AV media', -- canonical
'[Cc]ite audio', '[Cc]ite AV', '[Cc]ite AV ?Media', '[Cc]ite av media',
'[Cc]ite cd', '[Cc]ite DVD', '[Cc]ite dvd', '[Cc]ite film',
'[Cc]ite image', '[Cc]ite media', '[Cc]ite movie',
'[Cc]ite music video', '[Cc]ite radio', '[Cc]ite song',
'[Cc]ite ?video', '[Cc]ite visual', '[Cc]ite You[Tt]ube',
'[Cc]ita vídeo', -- non-English redirect; TODO: tally separately?
'[Cc]ite AV media notes', -- canonical
'[Cc]ite album[ %-]notes', '[Cc]ite av media notes',
'[Cc]ite DVD[ %-]notes', '[Cc]ite dvd%-notes', '[Cc]ite liner notes',
'[Cc]ite music release notes', '[Ll]iner notes',
'[Cc]ite bio[Rr]xiv', -- bioRxiv is the canonical form
'[Cc]ite [Bb]ook', -- book is the canonical form
'[Bb]ook cite', '[Bb]ook reference', '[Bb]ook reference url',
'[Cc] book', '[Cc]it book', '[Cc]ite books', '[Cc]ite chapter',
'[Cc]ite ebook', '[Cc]ite manual', '[Cc]ite page',
'[Cc]ite publication', '[Cc]ite score',
'[Cc]ite work', '[Cc]ite%-?book',
'[Bb]okref', '[Cc]itace monografie', '[Cc]itar livro', -- non-English redirects; TODO: tally separately?
'[Cc]iteer boek', '[Oo]uvrage', '[Rr]ef%-llibre', '서적 인용',
'[Cc]ite citeseerx', -- canonical
'[Cc]ite conference', -- canonical
'[Cc]ita conferenza', '[Cc]ite proceedings', '[Cc]onference reference', -- cita conferenza is non-English; TODO: tally separately?
'[Cc]ite ?encyclopedia', -- cite encyclopedia is the canonical name
'[Cc]ite contribution', '[Cc]ite dic', '[Cc]ite dictionary',
'[Cc]ite encyclopaedia', '[Cc]ite encyclopædia', '[Ee]ncyclopedia',
'[Cc]ite [Ee]pisode', -- episode is the canonical form
'[Cc]ite show',
'[Cc]ite interview', -- canonical
'[Cc]ite ?journal', -- cite journal is the canonical form
'[Cc] journal', '[Cc]itation journal', '[Cc]ite abstract',
'[Cc]ite document', '[Cc]ite Journal', '[Cc]ite journal zh',
'[Cc]ite ?paper', '[Vv]cite2 journal',
'[Cc]ita pubblicazione', '[Cc]itace periodika', '[Cc]itar jornal', -- non-English redirects; TODO: tally separately?
'[Cc]itar publicació', '[Cc]ytuj pismo', '[Tt]idskriftsref',
'Навод из стручног часописа', '저널 인용',
'[Cc]ite [Mm]agazine', -- magazine is the canonical form
'[Cc]ite mag', '[Cc]ite magazine article', '[Cc]ite newsletter',
'[Cc]ite periodical',
'[Cc]ite mailing ?list', -- mailing list is the canonical form
'[Cc]ite list',
'[Cc]ite maps?', -- map is the canonical form
'[Cc]ite[ %-]?news', -- cite news is the canonical form
'[Cc] news', '[Cc]it news', '[Cc]itation news', '[Cc]ite article',
'[Cc]ite n', '[Cc]ite new', '[Cc]ite newspaper', '[Cc]ite News',
'[Cc]ite news%-q', '[Cc]ite news2', '[Cc]itenewsauthor', '[Cc]ute news',
'[Cc]itar notícia', '[Hh]aber kaynağı', '[Tt]idningsref', 'استشهاد بخبر', -- non-English redirects; TODO: tally separately?
'뉴스 인용',
'[Cc]ite newsgroup', -- canonical
'[Cc]ite usenet',
'[Cc]ite podcast', -- canonical
'[Cc]ite [Pp]ress release', -- press release is the canonical form
'[Cc]ite media release', '[Cc]ite news release', '[Cc]ite pr',
'[Cc]ite press', '[Cc]ite press release\.', '[Cc]ite press[%-]?release',
'[Cc]ite report', -- canonical
'[Cc]ite serial', -- canonical
'[Cc]ite sign', -- canonical
'[Cc]ite plaque',
'[Cc]ite speech', -- canonical
'[Cc]ite ssrn', -- canonical
'[Cc]ite SSRN',
'[Cc]ite tech ?report', -- techreport is the canonical form
'[Cc]ite standard', '[Cc]ite technical report', '[Tt]echrep reference',
'[Cc]ite thesis', -- canonical
'[Cc]ite dissertation',
'[Cc]itar tese', -- non-English redirect; TODO: tally separately?
'[Cc]ite [Ww]eb', -- web is the canonical form
'[Cc] web', '[Cc]it web', '[Cc]ite blog', '[Cc]ite URL', '[Cc]ite url',
'[Cc]ite w', '[Cc]ite wb', '[Cc]ite we', '[Cc]ite web\.',
'[Cc]ite webpage', '[Cc]ite website', '[Cc]ite website article',
'[Cc]ite%-?web', '[Cc]itweb', '[Cc]w', '[Rr]ef web', '[Ww]eb citation',
'[Ww]eb cite', '[Ww]eb link', '[Ww]eb[ %-]reference', '[Ww]eblink',
'[Cc]hú thích web', '[Cc]ita web', '[Cc]itace elektronické monografie', -- non-English redirects; TODO: tally separately?
'[Cc]itat web', 'مرجع ويب', 'یادکرد وب', '웹 인용',
}
--[[--------------------------< C S 2 _ T E M P L A T E _ P A T T E R N S >------------------------------------
These are patterns for cs2 templates redirects.
]]
local cs2_template_patterns = { -- lua patterns of the cannonical names and redirects
'[Cc]itation',
'[Cc]ite', '[Cc]ite citation', '[Cc]ite study',
'[Cc]ite [Tt]echnical standard',
}
--[[--------------------------< V C I T E _ T E M P L A T E _ P A T T E R N S >--------------------------------
These are patterns for Vcite-family templates and their redirects.
]]
local vcite_template_patterns = {
'[Vv]cite book', -- canonical
'[Vv]ancite book', '[Vv]ancite report', '[Vv]cite encyclopedia',
'[Vv]cite report',
'[Vv]cite journal', -- canonical
'[Cc]it journal', '[Cc]it paper', '[Vv]ancite journal', '[Vv]cite paper',
'[Vv]cite news', -- canonical
'[Vv]ancite news',
'[Vv]cite web', -- canonical
'[Vv]ancite web',
}
--[[--------------------------< H A R V C _ T E M P L A T E _ P A T T E R N S >--------------------------------
These are patterns for the harvc template and its redirects.
]]
local harvc_template_patterns = {
'[Hh]arvc', -- canonical
'[Cc]itec',
}
--[[--------------------------< C S 1 _ L I K E _ T E M P L A T E _ P A T T E R N S >--------------------------
These are patterns for miscellaneous templates and their redirects that 'look like' cs1 templates (begin with cite ...)
Because they 'look like' cs1 templates they are handled as if they were cs1 templates. These templates are NOT
wrapper templates; names and dates are always to be extracted from the article instantiation of the template.
]]
local cs1_like_template_patterns = {
'[Cc]ite LSA', -- canonical
}
--[[--------------------------< W I K I C I T E _ T E M P L A T E _ P A T T E R N S >--------------------------
These are patterns for the wikicite template and its redirects.
]]
local wikicite_template_patterns = {
'[Ww]ikicite', -- canonical
}
--[[--------------------------< A N C H O R _ T E M P L A T E _ P A T T E R N S >------------------------------
These are patterns for the anchor template and its redirects.
]]
local anchor_template_patterns = {
'[Aa]nchors?', -- anchor is canonical form
'[Aa]nchor for redirect',
'[Aa]nchro',
'[Aa]ncor',
}
--[[--------------------------< S F N _ W H I T E L I S T _ P A T T E R N S >----------------------------------
These are patterns for the anchor template and its redirects.
]]
local sfn_whitelist_patterns = {
'[Ss]fn whitelist', -- canonical
'[Hh]arv whitelist',
}
--[[--------------------------< K N O W N _ T E M P L A T E S >------------------------------------------------
These tables are created from the *_template_patterns tables. To make these tables, entries in the source tables
are evaluated to replace lua patterns with the appropriate characters to create names for the output tables.
First charqacter is always uppercase
For example:
[Cc]ite ar[Xx]iv
becomes
Cite arXiv
Cite arxiv
]]
local known_templates_cs12 = {}; -- the exported tables
local known_templates_vcite = {};
local known_templates_harvc = {};
local known_templates_wikicite = {};
local known_templates_anchor = {};
local known_templates_sfn_whitelist = {};
local function add_stripped (list, name)
if not list[name] then
list[name] = true;
end
end
local function pattern_convert (pattern, list)
local lead, tail, c, l, name;
local first_char_patterns = {
'^%[(%a)%a%]', -- leading character (usually uppercase)
'^%[%a(%a)%]', -- leading character (usually lowercase)
}
c = tostring (pattern:match ('%u')); -- tostring() required because I don't know why; lua chokes complaining that c is not a string
name = pattern:gsub ('^%[%a%a%]', c); -- replace bracketed first character [Xx] with selected character from the match
if name:match ('(.-)%[(%a)(%a)%](.*)') then -- mixed case optional letters
lead, c, l, tail = name:match ('(.-)%[(%a)(%a)%](.*)');
add_stripped (list, lead .. c .. tail); -- uppercase
add_stripped (list, lead .. l .. tail); -- lowercase
elseif name:match ('^([^%[]+)(%[ %%%-%]%?)(.+)$') then -- [ %-]?
lead, c, tail = name:match ('^([^%[]+)(%[ %%%-%]%?)(.+)$');
add_stripped (list, lead .. tail); -- neither char
add_stripped (list, lead .. ' ' .. tail); -- space
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%[]+)(%[%%%-%]%?)(.+)$') then -- [%-]?
lead, c, tail = name:match ('^([^%[]+)(%[%%%-%]%?)(.+)$');
add_stripped (list, lead .. tail); -- no hyphen
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%[]+)(%[ %%%-%])(.+)$') then -- [ %-]
lead, c, tail = name:match ('^([^%[]+)(%[ %%%-%])(.+)$');
add_stripped (list, lead .. ' ' .. tail); -- space
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%?]+)(%%%-%?)(.+)$') then -- %-?
lead, c, tail = name:match ('^([^%?]+)(%%%-%?)(.+)$');
add_stripped (list, lead .. tail); -- no hyphen
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^(.-)(%%%-)(.+)$') then -- %-
lead, c, tail = name:match ('^(.-)(%%%-)(.+)$');
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^(.-)(.)%?(.*)$') then -- .?
lead, c, tail = name:match ('^(.-)(.)%?(.*)$');
add_stripped (list, lead .. tail); -- no character
add_stripped (list, lead .. c .. tail); -- character
else
add_stripped (list, name); -- no patterns so save as is
end
end
for _, t in ipairs ({
{cs1_template_patterns, known_templates_cs12},
{cs2_template_patterns, known_templates_cs12},
{cs1_like_template_patterns, known_templates_cs12},
{vcite_template_patterns, known_templates_vcite},
{harvc_template_patterns, known_templates_harvc},
{wikicite_template_patterns, known_templates_wikicite},
{anchor_template_patterns, known_templates_anchor},
{sfn_whitelist_patterns, known_templates_sfn_whitelist},
}) do
for _, pattern in ipairs (t[1]) do -- for each patern in *_template_patterns
pattern_convert (pattern, t[2]) -- convert and store in known_templates_*
end
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return
{
known_templates_anchor = known_templates_anchor,
known_templates_cs12 = known_templates_cs12,
known_templates_harvc = known_templates_harvc,
known_templates_vcite = known_templates_vcite,
known_templates_wikicite = known_templates_wikicite,
known_templates_sfn_whitelist = known_templates_sfn_whitelist,
}
6267b1029a020fb98adfa02a74118ae31897ac81
Module:Other uses
828
116
247
2020-06-01T23:06:08Z
Canopus >Nihiltres
0
Removed p.otheruses2 function per its template's deletion
Scribunto
text/plain
local mHatnote = require('Module:Hatnote')
local mHatlist = require('Module:Hatnote list')
local mArguments --initialize lazily
local mTableTools --initialize lazily
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local p = {}
-- Produces standard {{other uses}} implementation
function p.otheruses(frame)
mArguments = require('Module:Arguments')
mTableTools = require('Module:TableTools')
local args = mTableTools.compressSparseArray(mArguments.getArgs(frame))
local title = mw.title.getCurrentTitle().prefixedText
return p._otheruses(args, {title=title})
end
--Implements "other [x]" templates with otherText supplied at invocation
function p.otherX(frame)
mArguments = require('Module:Arguments')
mTableTools = require('Module:TableTools')
local x = frame.args[1]
local args = mTableTools.compressSparseArray(
mArguments.getArgs(frame, {parentOnly = true})
)
local options = {
title = mw.title.getCurrentTitle().prefixedText,
otherText = x
}
return p._otheruses(args, options)
end
-- Main generator
function p._otheruses(args, options)
--Type-checks and defaults
checkType('_otheruses', 1, args, 'table', true)
args = args or {}
checkType('_otheruses', 2, options, 'table')
if not (options.defaultPage or options.title) then
error('No default title data provided in "_otheruses" options table', 2)
end
local emptyArgs = true
for k, v in pairs(args) do
if type(k) == 'number' then emptyArgs = false break end
end
if emptyArgs then
args = {
options.defaultPage or
mHatnote.disambiguate(options.title, options.disambiguator)
}
end
--Generate and return hatnote
local text = mHatlist.forSeeTableToString({{
use = options.otherText and "other " .. options.otherText or nil,
pages = args
}})
return mHatnote._hatnote(text)
end
return p
2497cafae11ffa785bced56bc9f3853cf3bce7b1
Module:Pagetype
828
59
133
2020-06-18T21:22:08Z
Canopus >RexxS
0
add caps parameter per talk request
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- PAGETYPE --
-- --
-- This is a meta-module intended to replace {{pagetype}} and similar --
-- templates. It automatically detects namespaces, and allows for a --
-- great deal of customisation. It can easily be ported to other --
-- wikis by changing the values in the [[Module:Pagetype/config]]. --
-- --
--------------------------------------------------------------------------------
-- Load config.
local cfg = mw.loadData('Module:Pagetype/config')
-- Load required modules.
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local nsDetectModule = require('Module:Namespace detect')
local nsDetect = nsDetectModule._main
local getParamMappings = nsDetectModule.getParamMappings
local getPageObject = nsDetectModule.getPageObject
local p = {}
local function shallowCopy(t)
-- Makes a shallow copy of a table.
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
local function checkPagetypeInput(namespace, val)
-- Checks to see whether we need the default value for the given namespace,
-- and if so gets it from the pagetypes table.
-- The yesno function returns true/false for "yes", "no", etc., and returns
-- val for other input.
local ret = yesno(val, val)
if ret and type(ret) ~= 'string' then
ret = cfg.pagetypes[namespace]
end
return ret
end
local function getPagetypeFromClass(class, param, aliasTable, default)
-- Gets the pagetype from a class specified from the first positional
-- parameter.
param = yesno(param, param)
if param ~= false then -- No check if specifically disallowed.
for _, alias in ipairs(aliasTable) do
if class == alias then
if type(param) == 'string' then
return param
else
return default
end
end
end
end
end
local function getNsDetectValue(args)
-- Builds the arguments to pass to [[Module:Namespace detect]] and returns
-- the result.
-- Get the default values.
local ndArgs = {}
local defaultns = args[cfg.defaultns]
if defaultns == cfg.defaultnsAll then
ndArgs = shallowCopy(cfg.pagetypes)
else
local defaultnsArray
if defaultns == cfg.defaultnsExtended then
defaultnsArray = cfg.extendedNamespaces
elseif defaultns == cfg.defaultnsNone then
defaultnsArray = {}
else
defaultnsArray = cfg.defaultNamespaces
end
for _, namespace in ipairs(defaultnsArray) do
ndArgs[namespace] = cfg.pagetypes[namespace]
end
end
--[[
-- Add custom values passed in from the arguments. These overwrite the
-- defaults. The possible argument names are fetched from
-- Module:Namespace detect automatically in case new namespaces are
-- added. Although we accept namespace aliases as parameters, we only pass
-- the local namespace name as a parameter to Module:Namespace detect.
-- This means that the "image" parameter can overwrite defaults for the
-- File: namespace, which wouldn't work if we passed the parameters through
-- separately.
--]]
local mappings = getParamMappings()
for ns, paramAliases in pairs(mappings) do
-- Copy the aliases table, as # doesn't work with tables returned from
-- mw.loadData.
paramAliases = shallowCopy(paramAliases)
local paramName = paramAliases[1]
-- Iterate backwards along the array so that any values for the local
-- namespace names overwrite those for namespace aliases.
for i = #paramAliases, 1, -1 do
local paramAlias = paramAliases[i]
local ndArg = checkPagetypeInput(paramAlias, args[paramAlias])
if ndArg == false then
-- If any arguments are false, convert them to nil to protect
-- against breakage by future changes to
-- [[Module:Namespace detect]].
ndArgs[paramName] = nil
elseif ndArg then
ndArgs[paramName] = ndArg
end
end
end
-- Check for disambiguation-class and N/A-class pages in mainspace.
if ndArgs.main then
local class = args[1]
if type(class) == 'string' then
-- Put in lower case so e.g. "Dab" and "dab" will both match.
class = mw.ustring.lower(class)
end
local dab = getPagetypeFromClass(
class,
args[cfg.dab],
cfg.dabAliases,
cfg.dabDefault
)
if dab then
ndArgs.main = dab
else
local na = getPagetypeFromClass(
class,
args[cfg.na],
cfg.naAliases,
cfg.naDefault
)
if na then
ndArgs.main = na
end
end
end
-- If there is no talk value specified, use the corresponding subject
-- namespace for talk pages.
if not ndArgs.talk then
ndArgs.subjectns = true
end
-- Add the fallback value. This can also be customised, but it cannot be
-- disabled.
local other = args[cfg.other]
-- We will ignore true/false/nil results from yesno here, but using it
-- anyway for consistency.
other = yesno(other, other)
if type(other) == 'string' then
ndArgs.other = other
else
ndArgs.other = cfg.otherDefault
end
-- Allow custom page values.
ndArgs.page = args.page
return nsDetect(ndArgs)
end
local function detectRedirects(args)
local redirect = args[cfg.redirect]
-- The yesno function returns true/false for "yes", "no", etc., and returns
-- redirect for other input.
redirect = yesno(redirect, redirect)
if redirect == false then
-- Detect redirects unless they have been explicitly disallowed with
-- "redirect=no" or similar.
return
end
local pageObject = getPageObject(args.page)
-- If we are using subject namespaces elsewhere, do so here as well.
if pageObject
and not yesno(args.talk, true)
and args[cfg.defaultns] ~= cfg.defaultnsAll
then
pageObject = getPageObject(
pageObject.subjectNsText .. ':' .. pageObject.text
)
end
-- Allow custom values for redirects.
if pageObject and pageObject.isRedirect then
if type(redirect) == 'string' then
return redirect
else
return cfg.redirectDefault
end
end
end
function p._main(args)
local redirect = detectRedirects(args)
local pagetype = ""
if redirect then
pagetype = redirect
else
pagetype = getNsDetectValue(args)
end
if yesno(args.plural, false) then
if cfg.irregularPlurals[pagetype] then
pagetype = cfg.irregularPlurals[pagetype]
else
pagetype = pagetype .. cfg.plural -- often 's'
end
end
if yesno(args.caps, false) then
pagetype = mw.ustring.upper(mw.ustring.sub(pagetype, 1, 1)) ..
mw.ustring.sub(pagetype, 2)
end
return pagetype
end
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
return p
210524e0c60e3354325aea88c508e94423ad228d
Template:SfnRef
10
101
217
2020-07-04T15:54:11Z
Canopus >Ahecht
0
safesubst<noinclude />:
wikitext
text/x-wiki
{{safesubst<noinclude />:#invoke:Footnotes|sfnref}}<noinclude>
{{documentation}}
</noinclude>
56e03dd26fcd9edbe71a96b5c5c84198863b964b
Module:String
828
71
157
2020-08-02T15:49:42Z
Canopus >RexxS
0
separate annotations for str.match from those for str._match
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} )
local s = new_args['s'] or ''
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } )
local s = new_args['s'] or ''
local i = tonumber( new_args['i'] ) or 1
local j = tonumber( new_args['j'] ) or -1
local len = mw.ustring.len( s )
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1
end
if j < 0 then
j = len + j + 1
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'String subset index out of range' )
end
if j < i then
return str._error( 'String subset indices out of order' )
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
_match
This function returns a substring from the source string that matches a
specified pattern. It is exported for use in other modules
Usage:
strmatch = require("Module:String")._match
sresult = strmatch( s, pattern, start, match, plain, nomatch )
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This sub-routine is exported for use in other modules
function str._match( s, pattern, start, match_index, plain_flag, nomatch )
if s == '' then
return str._error( 'Target string is empty' )
end
if pattern == '' then
return str._error( 'Pattern string is empty' )
end
start = tonumber(start) or 1
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Requested start is out of range' )
end
if match_index == 0 then
return str._error( 'Match index is out of range' )
end
if plain_flag then
pattern = str._escapePattern( pattern )
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start )
end
local iterator = mw.ustring.gmatch(s, pattern)
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1
if match_index == 0 then
result = w
break
end
end
else
-- Reverse search
local result_table = {}
local count = 1
for w in iterator do
result_table[count] = w
count = count + 1
end
result = result_table[ count + match_index ]
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Match not found' )
else
return nomatch
end
else
return result
end
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This is the entry point for #invoke:String|match
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} )
local s = new_args['s'] or ''
local start = tonumber( new_args['start'] ) or 1
local plain_flag = str._getBoolean( new_args['plain'] or false )
local pattern = new_args['pattern'] or ''
local match_index = math.floor( tonumber(new_args['match']) or 1 )
local nomatch = new_args['nomatch']
return str._match( s, pattern, start, match_index, plain_flag, nomatch )
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} )
local target_str = new_args['target'] or ''
local pos = tonumber( new_args['pos'] ) or 0
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'String index out of range' )
end
return mw.ustring.sub( target_str, pos, pos )
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} )
local source_str = new_args['source'] or ''
local target_str = new_args['target'] or ''
if target_str == '' then
return 1
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['target'] or ''
local start_pos = tonumber(new_args['start']) or 1
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return 0
end
plain = str._getBoolean( plain )
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['pattern'] or ''
local replace = new_args['replace'] or ''
local count = tonumber( new_args['count'] )
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return source_str
end
plain = str._getBoolean( plain )
if plain then
pattern = str._escapePattern( pattern )
replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
end
local result
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count )
else
result = mw.ustring.gsub( source_str, pattern, replace )
end
return result
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
escapePattern
This function escapes special characters from a Lua string pattern. See [1]
for details on how patterns work.
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
Usage:
{{#invoke:String|escapePattern|pattern_string}}
Parameters
pattern_string: The pattern string to escape.
]]
function str.escapePattern( frame )
local pattern_str = frame.args[1]
if not pattern_str then
return str._error( 'No pattern string specified' )
end
local result = str._escapePattern( pattern_str )
return result
end
--[[
count
This function counts the number of occurrences of one string in another.
]]
function str.count(frame)
local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'})
local source = args.source or ''
local pattern = args.pattern or ''
local plain = str._getBoolean(args.plain or true)
if plain then
pattern = str._escapePattern(pattern)
end
local _, count = mw.ustring.gsub(source, pattern, '')
return count
end
--[[
endswith
This function determines whether a string ends with another string.
]]
function str.endswith(frame)
local args = str._getParameters(frame.args, {'source', 'pattern'})
local source = args.source or ''
local pattern = args.pattern or ''
if pattern == '' then
-- All strings end with the empty string.
return "yes"
end
if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then
return "yes"
else
return ""
end
end
--[[
join
Join all non empty arguments together; the first argument is the separator.
Usage:
{{#invoke:String|join|sep|one|two|three}}
]]
function str.join(frame)
local args = {}
local sep
for _, v in ipairs( frame.args ) do
if sep then
if v ~= '' then
table.insert(args, v)
end
else
sep = v
end
end
return table.concat( args, sep or '' )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {}
local index = 1
local value
for _, arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index]
index = index + 1
end
new_args[arg] = value
end
return new_args
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame()
local error_category = frame.args.error_category or 'Errors reported by Module String'
local ignore_errors = frame.args.ignore_errors or false
local no_category = frame.args.no_category or false
if str._getBoolean(ignore_errors) then
return ''
end
local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>'
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Category:' .. error_category .. ']]' .. error_str
end
return error_str
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower()
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false
else
boolean_value = true
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str
else
error( 'No boolean value found' )
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
end
return str
6df794dd52434e0f6a372c9918f5a9dedd15f579
Template:SDcat
10
68
151
2020-08-07T18:02:31Z
Canopus >MusikBot II
0
Protected "[[Template:SDcat]]": [[Wikipedia:High-risk templates|High-risk template or module]] ([[User:MusikBot II/TemplateProtector|more info]]) ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
wikitext
text/x-wiki
<includeonly>{{#invoke:SDcat |setCat}}</includeonly><noinclude>
{{documentation}}
</noinclude>
8c6e8783ddb0dc699d6fb60370db97b73725b9a6
Template:Convert
10
95
205
2020-08-09T22:52:24Z
Canopus >Bsherr
0
adding comment
wikitext
text/x-wiki
<includeonly>{{{{{♥|safesubst:}}}#invoke:convert|convert}}</includeonly><noinclude>
{{documentation}}
<!-- Add categories to the /doc subpage, interwikis to Wikidata, not here -->
</noinclude>
952ac4080dc4a427c4a65db9951c8a4f4c91c626
Module:SDcat
828
72
159
2020-08-16T17:20:37Z
Canopus >RexxS
0
if no connection to Wikidata, then do nothing
Scribunto
text/plain
--[[
SDcat
Module to check whether local short description matches that on Wikidata
--]]
local p = {}
-------------------------------------------------------------------------------
--[[
setCat has the qid of a Wikidata entity passed as |qid=
(it defaults to the associated qid of the current article if omitted)
and the local short description passed as |sd=
It returns a category if there is an associated Wikidata entity.
It returns one of the following tracking categories, as appropriate:
* Category:Short description matches Wikidata (case-insensitive)
* Category:Short description is different from Wikidata
* Category:Short description with empty Wikidata description
For testing purposes, a link prefix |lp= may be set to ":" to make the categories visible.
--]]
-- function exported for use in other modules
-- (local short description, Wikidata entity-ID, link prefix)
p._setCat = function(sdesc, itemID, lp)
if not mw.wikibase then return nil end
if itemID == "" then itemID = nil end
-- Wikidata description field
local wdesc = (mw.wikibase.getDescription(itemID) or ""):lower()
if wdesc == "" then
return "[[" .. lp .. "Category:Short description with empty Wikidata description]]"
elseif wdesc == sdesc then
return "[[" .. lp .. "Category:Short description matches Wikidata]]"
else
return "[[" .. lp .. "Category:Short description is different from Wikidata]]"
end
end
-- function exported for call from #invoke
p.setCat = function(frame)
local args
if frame.args.sd then
args = frame.args
else
args = frame:getParent().args
end
-- local short description
local sdesc = mw.text.trim(args.sd or ""):lower()
-- Wikidata entity-ID
local itemID = mw.text.trim(args.qid or "")
-- link prefix, strip quotes
local lp = mw.text.trim(args.lp or ""):gsub('"', '')
return p._setCat(sdesc, itemID, lp)
end
return p
6c19ac0f72c79a618eb105808f74701376bb2b38
Module:Portal/images/o
828
136
287
2020-09-15T07:16:03Z
Canopus >Northamerica1000
0
Addition: ["ocean"] = "Waves in pacifica 1.jpg|alt=icon",. rw: ["oceans"] = "Waves in pacifica 1.jpg|alt=icon",
Scribunto
text/plain
--[==[ This is the "O" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "O". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be omitted.
]==]
return {
["oaxaca"] = "Flag of Oaxaca.svg|border|link=|alt=flag",
["occult"] = "Pentacle 2.svg|link=|alt=",
["oceania"] = "大洋.png|alt=icon",
["ocean"] = "Waves in pacifica 1.jpg|alt=icon",
["oceans"] = "Waves in pacifica 1.jpg|alt=icon",
["odense"] = "Coat of arms of Odense.svg|alt=icon",
["odessa"] = "Flag of Odessa.svg|alt=flag",
["odisha"] = "Seal of Odisha.png|link=|alt=seal",
["ohio"] = "Flag of Ohio.svg|link=|alt=flag",
["ohio wesleyan university"] = "ElliottHallOWU.jpg|link=|alt=photo",
["oklahoma"] = "Flag of Oklahoma.svg|border|link=|alt=flag",
["olives"] = "NCI 2 green olives.jpg|link=|alt=",
["olympic games"] = "Olympic Rings.svg|link=|alt=",
["olympics"] = "Olympic Rings.svg|link=|alt=",
["omaha"] = "Flag of Omaha, Nebraska.jpg|link=|alt=flag",
["oman"] = "Flag of Oman.svg|border|link=|alt=flag",
["ontario"] = "Flag of Ontario.svg|border|link=|alt=flag",
["ontario regions"] = "Ontario-flag-contour.png|link=|alt=",
["opera"] = "Operalogo.svg|alt=icon",
["oregon"] = "Flag of Oregon.svg|border|link=|alt=flag",
["organic chemistry"] = "Covalent.svg|alt=icon",
["organized labour"] = "Syndicalism.svg|alt=icon",
["oriental orthodoxy"] = "CopticCross.jpg|link=|alt=",
["origami"] = "Origami-crane.jpg|alt=icon",
["osaka"] = "Flag of Osaka City.svg|border|link=|alt=flag",
["osaka university"] = "Toyonaka stone.png|alt=icon",
["oscar wilde"] = "Oscar Wilde, 1882.jpg|link=|alt=",
["ossetian"] = "Idioma osetio.png|border|link=Ossetian language|alt=map",
["ottawa"] = "Flag of Ottawa, Ontario.svg|border|link=|alt=flag",
["ottoman empire"] = "Flag of the Ottoman Empire.svg|border|link=|alt=flag",
["outlines"] = "Global thinking.svg|link=|alt=",
["oxfordshire"] = "EnglandOxfordshire.png|alt=icon",
["oz"] = "Oz flag.svg|alt=icon"
}
fb254fb478a7be48fd87d03b9e5017a96ddb900c
Template:RA
10
139
293
2020-10-16T16:34:12Z
Canopus >Jonesey95
0
fix extra space before template when rendered
wikitext
text/x-wiki
{{nowrap|{{#if:{{{1|}}}|{{{1}}}<sup>h</sup>|}} {{#if:{{{2|}}}|{{{2}}}<sup>m</sup>|}} {{#if:{{{3|}}}|{{{3|}}}<sup>s</sup>|}}}}<noinclude>
{{documentation}}
</noinclude>
f457f7f0663d084c3d3296af8b827dc417ce0ac4
Template:OEDsub
10
134
283
2020-11-22T09:35:49Z
Canopus >Mathglot
0
"Participating institution" membership required; not "UK public library". Many other institutions, like Athens, most US colleges and universities, and many public libraries in the US provide access.
wikitext
text/x-wiki
{{link note|note={{#ifeq: {{{sentence|no}}} | yes | S | s }}ubscription or [https://www.oed.com/public/login/loggingin#withyourlibrary participating institution membership] required{{#ifeq: {{{sentence|no}}} | yes | . | }}}}<noinclude>
{{Documentation}}
</noinclude>
66a4cfbe3af90f20ac87af655115d9debd61bb56
Template:Sfn
10
100
215
2021-01-14T23:46:10Z
Canopus >Jonesey95
0
add undocumented "ignore-err" (which should be "ignore-error", no?) to error check per a note on my talk page
wikitext
text/x-wiki
<includeonly>{{#invoke:Footnotes|sfn|template=sfn}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using sfn with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Sfn]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | 3 | 4 | 5 | ignore-err | loc | p | page | pages | postscript | pp | ps | ref | Ref }}<noinclude>
{{documentation}}
</noinclude>
eab6519b2a87e18dc40f39343c71f5848977cc93
Template:Reflist/styles.css
10
88
191
2021-03-08T23:00:26Z
Canopus >Izno
0
Changed protection level for "[[Template:Reflist/styles.css]]": match parent ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
text
text/plain
/* {{pp|small=yes}} */
/* can we remove the font size declarations? .references gets a font-size in
* common.css that is always 90, and there is nothing else in reflist out in
* the wild. May affect column sizes.
*/
.reflist {
font-size: 90%; /* Default font-size */
margin-bottom: 0.5em;
list-style-type: decimal;
}
.reflist .references {
font-size: 100%; /* Reset font-size when nested in div.reflist */
margin-bottom: 0; /* Avoid double margin when nested in div.reflist */
list-style-type: inherit; /* Enable custom list style types */
}
/* columns-2 and columns-3 are legacy for "2 or more" column view from when the
* template was implemented with column-count.
*/
.reflist-columns-2 {
column-width: 30em;
}
.reflist-columns-3 {
column-width: 25em;
}
/* Reset top margin for lists embedded in columns */
.reflist-columns {
margin-top: 0.3em;
}
.reflist-columns ol {
margin-top: 0;
}
/* Avoid elements breaking between columns */
.reflist-columns li {
page-break-inside: avoid; /* Removed from CSS in favor of break-inside c. 2020 */
break-inside: avoid-column;
}
.reflist-upper-alpha {
list-style-type: upper-alpha;
}
.reflist-upper-roman {
list-style-type: upper-roman;
}
.reflist-lower-alpha {
list-style-type: lower-alpha;
}
.reflist-lower-greek {
list-style-type: lower-greek;
}
.reflist-lower-roman {
list-style-type: lower-roman;
}
531a26d48f0e7826c61f764cfb7d5fb200032c34
Module:Math
828
127
269
2021-03-11T22:23:48Z
Canopus >Primefac
0
typo fix
Scribunto
text/plain
--[[
This module provides a number of basic mathematical operations.
]]
local yesno, getArgs -- lazily initialized
local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules.
local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.
--[[
Helper functions used to avoid redundant code.
]]
local function err(msg)
-- Generates wikitext error messages.
return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg)
end
local function unpackNumberArgs(args)
-- Returns an unpacked list of arguments specified with numerical keys.
local ret = {}
for k, v in pairs(args) do
if type(k) == 'number' then
table.insert(ret, v)
end
end
return unpack(ret)
end
local function makeArgArray(...)
-- Makes an array of arguments from a list of arguments that might include nils.
local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs.
local nums = {} -- Stores the numbers of valid numerical arguments.
local ret = {}
for k, v in pairs(args) do
v = p._cleanNumber(v)
if v then
nums[#nums + 1] = k
args[k] = v
end
end
table.sort(nums)
for i, num in ipairs(nums) do
ret[#ret + 1] = args[num]
end
return ret
end
local function fold(func, ...)
-- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters,
-- and must return a number as an output. This number is then supplied as input to the next function call.
local vals = makeArgArray(...)
local count = #vals -- The number of valid arguments
if count == 0 then return
-- Exit if we have no valid args, otherwise removing the first arg would cause an error.
nil, 0
end
local ret = table.remove(vals, 1)
for _, val in ipairs(vals) do
ret = func(ret, val)
end
return ret, count
end
--[[
Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value).
]]
local function binary_fold(func, ...)
local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...)
return value
end
--[[
random
Generate a random number
Usage:
{{#invoke: Math | random }}
{{#invoke: Math | random | maximum value }}
{{#invoke: Math | random | minimum value | maximum value }}
]]
function wrap.random(args)
local first = p._cleanNumber(args[1])
local second = p._cleanNumber(args[2])
return p._random(first, second)
end
function p._random(first, second)
math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000))
-- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params.
if first and second then
if first <= second then -- math.random doesn't allow the first number to be greater than the second.
return math.random(first, second)
end
elseif first then
return math.random(first)
else
return math.random()
end
end
--[[
order
Determine order of magnitude of a number
Usage:
{{#invoke: Math | order | value }}
]]
function wrap.order(args)
local input_string = (args[1] or args.x or '0');
local input_number = p._cleanNumber(input_string);
if input_number == nil then
return err('order of magnitude input appears non-numeric')
else
return p._order(input_number)
end
end
function p._order(x)
if x == 0 then return 0 end
return math.floor(math.log10(math.abs(x)))
end
--[[
precision
Detemines the precision of a number using the string representation
Usage:
{{ #invoke: Math | precision | value }}
]]
function wrap.precision(args)
local input_string = (args[1] or args.x or '0');
local trap_fraction = args.check_fraction;
local input_number;
if not yesno then
yesno = require('Module:Yesno')
end
if yesno(trap_fraction, true) then -- Returns true for all input except nil, false, "no", "n", "0" and a few others. See [[Module:Yesno]].
local pos = string.find(input_string, '/', 1, true);
if pos ~= nil then
if string.find(input_string, '/', pos + 1, true) == nil then
local denominator = string.sub(input_string, pos+1, -1);
local denom_value = tonumber(denominator);
if denom_value ~= nil then
return math.log10(denom_value);
end
end
end
end
input_number, input_string = p._cleanNumber(input_string);
if input_string == nil then
return err('precision input appears non-numeric')
else
return p._precision(input_string)
end
end
function p._precision(x)
if type(x) == 'number' then
x = tostring(x)
end
x = string.upper(x)
local decimal = x:find('%.')
local exponent_pos = x:find('E')
local result = 0;
if exponent_pos ~= nil then
local exponent = string.sub(x, exponent_pos + 1)
x = string.sub(x, 1, exponent_pos - 1)
result = result - tonumber(exponent)
end
if decimal ~= nil then
result = result + string.len(x) - decimal
return result
end
local pos = string.len(x);
while x:byte(pos) == string.byte('0') do
pos = pos - 1
result = result - 1
if pos <= 0 then
return 0
end
end
return result
end
--[[
max
Finds the maximum argument
Usage:
{{#invoke:Math| max | value1 | value2 | ... }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.max(args)
return p._max(unpackNumberArgs(args))
end
function p._max(...)
local max_value = binary_fold((function(a, b) return a > b end), ...)
if max_value then
return max_value
end
end
--[[
median
Find the median of set of numbers
Usage:
{{#invoke:Math | median | number1 | number2 | ...}}
OR
{{#invoke:Math | median }}
]]
function wrap.median(args)
return p._median(unpackNumberArgs(args))
end
function p._median(...)
local vals = makeArgArray(...)
local count = #vals
table.sort(vals)
if count == 0 then
return 0
end
if p._mod(count, 2) == 0 then
return (vals[count/2] + vals[count/2+1])/2
else
return vals[math.ceil(count/2)]
end
end
--[[
min
Finds the minimum argument
Usage:
{{#invoke:Math| min | value1 | value2 | ... }}
OR
{{#invoke:Math| min }}
When used with no arguments, it takes its input from the parent
frame. Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.min(args)
return p._min(unpackNumberArgs(args))
end
function p._min(...)
local min_value = binary_fold((function(a, b) return a < b end), ...)
if min_value then
return min_value
end
end
--[[
sum
Finds the sum
Usage:
{{#invoke:Math| sum | value1 | value2 | ... }}
OR
{{#invoke:Math| sum }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.sum(args)
return p._sum(unpackNumberArgs(args))
end
function p._sum(...)
local sums, count = fold((function(a, b) return a + b end), ...)
if not sums then
return 0
else
return sums
end
end
--[[
average
Finds the average
Usage:
{{#invoke:Math| average | value1 | value2 | ... }}
OR
{{#invoke:Math| average }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.average(args)
return p._average(unpackNumberArgs(args))
end
function p._average(...)
local sum, count = fold((function(a, b) return a + b end), ...)
if not sum then
return 0
else
return sum / count
end
end
--[[
round
Rounds a number to specified precision
Usage:
{{#invoke:Math | round | value | precision }}
--]]
function wrap.round(args)
local value = p._cleanNumber(args[1] or args.value or 0)
local precision = p._cleanNumber(args[2] or args.precision or 0)
if value == nil or precision == nil then
return err('round input appears non-numeric')
else
return p._round(value, precision)
end
end
function p._round(value, precision)
local rescale = math.pow(10, precision or 0);
return math.floor(value * rescale + 0.5) / rescale;
end
--[[
log10
returns the log (base 10) of a number
Usage:
{{#invoke:Math | log10 | x }}
]]
function wrap.log10(args)
return math.log10(args[1])
end
--[[
mod
Implements the modulo operator
Usage:
{{#invoke:Math | mod | x | y }}
--]]
function wrap.mod(args)
local x = p._cleanNumber(args[1])
local y = p._cleanNumber(args[2])
if not x then
return err('first argument to mod appears non-numeric')
elseif not y then
return err('second argument to mod appears non-numeric')
else
return p._mod(x, y)
end
end
function p._mod(x, y)
local ret = x % y
if not (0 <= ret and ret < y) then
ret = 0
end
return ret
end
--[[
gcd
Calculates the greatest common divisor of multiple numbers
Usage:
{{#invoke:Math | gcd | value 1 | value 2 | value 3 | ... }}
--]]
function wrap.gcd(args)
return p._gcd(unpackNumberArgs(args))
end
function p._gcd(...)
local function findGcd(a, b)
local r = b
local oldr = a
while r ~= 0 do
local quotient = math.floor(oldr / r)
oldr, r = r, oldr - quotient * r
end
if oldr < 0 then
oldr = oldr * -1
end
return oldr
end
local result, count = fold(findGcd, ...)
return result
end
--[[
precision_format
Rounds a number to the specified precision and formats according to rules
originally used for {{template:Rnd}}. Output is a string.
Usage:
{{#invoke: Math | precision_format | number | precision }}
]]
function wrap.precision_format(args)
local value_string = args[1] or 0
local precision = args[2] or 0
return p._precision_format(value_string, precision)
end
function p._precision_format(value_string, precision)
-- For access to Mediawiki built-in formatter.
local lang = mw.getContentLanguage();
local value
value, value_string = p._cleanNumber(value_string)
precision = p._cleanNumber(precision)
-- Check for non-numeric input
if value == nil or precision == nil then
return err('invalid input when rounding')
end
local current_precision = p._precision(value)
local order = p._order(value)
-- Due to round-off effects it is neccesary to limit the returned precision under
-- some circumstances because the terminal digits will be inaccurately reported.
if order + precision >= 14 then
if order + p._precision(value_string) >= 14 then
precision = 13 - order;
end
end
-- If rounding off, truncate extra digits
if precision < current_precision then
value = p._round(value, precision)
current_precision = p._precision(value)
end
local formatted_num = lang:formatNum(math.abs(value))
local sign
-- Use proper unary minus sign rather than ASCII default
if value < 0 then
sign = '−'
else
sign = ''
end
-- Handle cases requiring scientific notation
if string.find(formatted_num, 'E', 1, true) ~= nil or math.abs(order) >= 9 then
value = value * math.pow(10, -order)
current_precision = current_precision + order
precision = precision + order
formatted_num = lang:formatNum(math.abs(value))
else
order = 0;
end
formatted_num = sign .. formatted_num
-- Pad with zeros, if needed
if current_precision < precision then
local padding
if current_precision <= 0 then
if precision > 0 then
local zero_sep = lang:formatNum(1.1)
formatted_num = formatted_num .. zero_sep:sub(2,2)
padding = precision
if padding > 20 then
padding = 20
end
formatted_num = formatted_num .. string.rep('0', padding)
end
else
padding = precision - current_precision
if padding > 20 then
padding = 20
end
formatted_num = formatted_num .. string.rep('0', padding)
end
end
-- Add exponential notation, if necessary.
if order ~= 0 then
-- Use proper unary minus sign rather than ASCII default
if order < 0 then
order = '−' .. lang:formatNum(math.abs(order))
else
order = lang:formatNum(order)
end
formatted_num = formatted_num .. '<span style="margin:0 .15em 0 .25em">×</span>10<sup>' .. order .. '</sup>'
end
return formatted_num
end
--[[
divide
Implements the division operator
Usage:
{{#invoke:Math | divide | x | y | round= | precision= }}
--]]
function wrap.divide(args)
local x = args[1]
local y = args[2]
local round = args.round
local precision = args.precision
if not yesno then
yesno = require('Module:Yesno')
end
return p._divide(x, y, yesno(round), precision)
end
function p._divide(x, y, round, precision)
if y == nil or y == "" then
return err("Empty divisor")
elseif not tonumber(y) then
if type(y) == 'string' and string.sub(y, 1, 1) == '<' then
return y
else
return err("Not a number: " .. y)
end
elseif x == nil or x == "" then
return err("Empty dividend")
elseif not tonumber(x) then
if type(x) == 'string' and string.sub(x, 1, 1) == '<' then
return x
else
return err("Not a number: " .. x)
end
else
local z = x / y
if round then
return p._round(z, 0)
elseif precision then
return p._round(z, precision)
else
return z
end
end
end
--[[
Helper function that interprets the input numerically. If the
input does not appear to be a number, attempts evaluating it as
a parser functions expression.
]]
function p._cleanNumber(number_string)
if type(number_string) == 'number' then
-- We were passed a number, so we don't need to do any processing.
return number_string, tostring(number_string)
elseif type(number_string) ~= 'string' or not number_string:find('%S') then
-- We were passed a non-string or a blank string, so exit.
return nil, nil;
end
-- Attempt basic conversion
local number = tonumber(number_string)
-- If failed, attempt to evaluate input as an expression
if number == nil then
local success, result = pcall(mw.ext.ParserFunctions.expr, number_string)
if success then
number = tonumber(result)
number_string = tostring(number)
else
number = nil
number_string = nil
end
else
number_string = number_string:match("^%s*(.-)%s*$") -- String is valid but may contain padding, clean it.
number_string = number_string:match("^%+(.*)$") or number_string -- Trim any leading + signs.
if number_string:find('^%-?0[xX]') then
-- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead.
number_string = tostring(number)
end
end
return number, number_string
end
--[[
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.
]]
local mt = { __index = function(t, k)
return function(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return wrap[k](getArgs(frame)) -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.
end
end }
return setmetatable(p, mt)
2bbe734d898299f65412963a3c1782e9fcc4d9ca
Module:Template wrapper
828
125
265
2021-05-08T08:01:01Z
Canopus >GKFX
0
Add uncopyable line break opportunities to documentation mode
Scribunto
text/plain
require('Module:No globals');
local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">|_template=</code> missing or empty</span>';
--[[--------------------------< I S _ I N _ T A B L E >--------------------------------------------------------
scan through tbl looking for value; return true if found, false else
]]
local function is_in_table (tbl, value)
for k, v in pairs (tbl) do
if v == value then return true end
end
return false;
end
--[[--------------------------< A D D _ P A R A M E T E R >----------------------------------------------------
adds parameter name and its value to args table according to the state of boolean list argument; kv pair for
template execution; k=v string for template listing.
]]
local function add_parameter (k, v, args, list)
if list then
table.insert( args, table.concat ({k, '=', v})); -- write parameter names and values to args table as string
else
args[k] = v; -- copy parameters to args table
end
end
--[[--------------------------< A L I A S _ M A P _ G E T >----------------------------------------------------
returns a table of local template (parent frame) parameter names and the target template names that match where
in [key]=<value> pairs where:
[key] is local template parameter name (an alias)
<value> is target template parameter name (the canonical parameter name used in the working template)
The parameter |_alias-map= has the form:
|_alias-map=<list>
where <list> is a comma-separated list of alias / canonical parameter name pairs in the form
<from> : <to>
where:
<from> is the local template's parameter name (alias)
<to> is the target template's parameter name (canonical)
for enumerated parameters place an octothorp (#) where the enumerator digits are placed in the parameter names:
<from#> : <to#>
]]
local function alias_map_get (_alias_map)
local T = mw.text.split (_alias_map, '%s*,%s*'); -- convert the comma-separated list into a table of alias pairs
local mapped_aliases = {}; -- mapped aliases will go here
local l_name, t_name; -- parameter names
for _, alias_pair in ipairs (T) do -- loop through the table of alias pairs
l_name, t_name = alias_pair:match ('(.-)%s*:%s*(.+)'); -- from each pair, get local and target parameter names
if l_name and t_name then -- if both are set
if tonumber (l_name) then
l_name = tonumber (l_name); -- convert number-as-text to a number
end
mapped_aliases[l_name] = t_name; -- add them to the map table
end
end
return mapped_aliases;
end
--[[--------------------------< F R A M E _ A R G S _ G E T >--------------------------------------------------
Fetch the wrapper template's 'default' and control parameters; adds default parameters to args
returns content of |_template= parameter (name of the working template); nil else
]]
local function frame_args_get (frame_args, args, list)
local template;
for k, v in pairs (frame_args) do -- here we get the wrapper template's 'default' parameters
if 'string' == type (k) and (v and ('' ~= v)) then -- do not pass along positional or empty parameters
if '_template' == k then
template = v; -- save the name of template that we are wrapping
elseif '_exclude' ~= k and '_reuse' ~= k and '_include-positional' ~= k and '_alias-map' ~= k then -- these already handled so ignore here;
add_parameter (k, v, args, list); -- add all other parameters to args in the style dictated by list
end
end
end
return template; -- return contents of |_template= parameter
end
--[=[--------------------------< P F R A M E _ A R G S _ G E T >------------------------------------------------
Fetches the wrapper template's 'live' parameters; adds live parameters that aren't members of the exclude table to
args table; positional parameters may not be excluded
no return value
]=]
local function pframe_args_get (pframe_args, args, exclude, _include_positional, list)
for k, v in pairs (pframe_args) do
if 'string' == type (k) and not is_in_table (exclude, k) then -- do not pass along excluded parameters
if v and ('' ~= v) then -- pass along only those parameters that have assigned values
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (k, v, args, list) -- add all other parameters to args in the style dictated by list; alias map only supported for local-template parameters
end
end
end
if _include_positional then
for i, v in ipairs (pframe_args) do -- pass along positional parameters
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (i, v, args, list);
end
end
end
--[[--------------------------< _ M A I N >--------------------------------------------------------------------
Collect the various default and live parameters into args styled according to boolean list.
returns name of the working or listed template or nil for an error message
]]
local function _main (frame, args, list)
local template;
local exclude = {}; -- table of parameter names for parameters that are not passed to the working template
local reuse_list = {}; -- table of pframe parameter names whose values are modified before they are passed to the working template as the same name
local alias_map = {}; -- table that maps parameter aliases to working template canonical parameter names
local _include_positional;
if frame.args._exclude and ('' ~= frame.args._exclude) then -- if there is |_exclude= and it's not empty
exclude = mw.text.split (frame.args._exclude, "%s*,%s*"); -- make a table from its contents
end
-- TODO: |_reuse= needs a better name (|_reuse=)
if frame.args._reuse and ('' ~= frame.args._reuse) then -- if there is |_reuse= and it's not empty
reuse_list = mw.text.split (frame.args._reuse, "%s*,%s*"); -- make a table from its contents
end
if frame.args['_alias-map'] and ('' ~= frame.args['_alias-map']) then -- if there is |_alias-map= and it's not empty
alias_map = alias_map_get (frame.args['_alias-map']); -- make a table from its contents
end
template = frame_args_get (frame.args, args, list); -- get parameters provided in the {{#invoke:template wrapper|...|...}}
if nil == template or '' == template then -- this is the one parameter that is required by this module
return nil; -- not present, tell calling function to emit an error message
end
_include_positional = 'yes' == frame.args['_include-positional']; -- when true pass all positional parameters along with non-excluded named parameters to ...
-- ... the working template; positional parameters are not excludable
local _pframe_args = frame:getParent().args; -- here we get the wrapper template's 'live' parameters from pframe.args
local pframe_args = {}; -- a local table that we can modify
for k, v in pairs (_pframe_args) do -- make a copy that we can modify
pframe_args[k] = v;
end
-- here we look for pframe parameters that are aliases of canonical parameter names; when found
-- we replace the alias with the canonical. We do this here because the reuse_list works on
-- canonical parameter names so first we convert alias parameter names to canonical names and then
-- we remove those canonical names from the pframe table that are reused (provided to the working
-- template through the frame args table)
for k, v in pairs (alias_map) do -- k is alias name, v is canonical name
if pframe_args[k] then -- if pframe_args has parameter with alias name
pframe_args[v] = _pframe_args[k]; -- create new canonical name with alias' value
pframe_args[k] = nil; -- unset the alias
end
end
for k, v in pairs (pframe_args) do -- do enumerated parameter alias -> canonical translation
if 'string' == type (k) then -- only named parameters can be enumerated
if alias_map[k..'#'] then -- non-enumerated alias matches enumerated parameter pattern? enumerator at end only
pframe_args[alias_map[k..'#']:gsub('#', '')] = v; -- remove '#' and copy parameter to pframe_args table
pframe_args[k] = nil; -- unset the alias
elseif k:match ('%d+') then -- if this parameter name contains digits
local temp = k:gsub ('%d+', '#'); -- make a copy; digits replaced with single '#'
local enum = k:match ('%d+'); -- get the enumerator
if alias_map[temp] then -- if this parameter is a recognized enumerated alias
pframe_args[alias_map[temp]:gsub('#', enum)] = v; -- use canonical name and replace '#' with enumerator and add to pframe_args
pframe_args[k] = nil; -- unset the alias
end
end
end
end
-- pframe parameters that are _reused are 'reused' have the form something like this:
-- |chapter=[[wikisource:{{{chapter}}}|{{{chapter}}}]]
-- where a parameter in the wrapping template is modified and then passed to the working template
-- using the same parameter name (in this example |chapter=)
-- remove parameters that will be reused
for k, v in ipairs (reuse_list) do -- k is numerical index, v is canonical parameter name to ignore
if pframe_args[v] then -- if pframe_args has parameter that should be ignored
pframe_args[v] = nil; -- unset the ignored parameter
end
end
pframe_args_get (pframe_args, args, exclude, _include_positional, list); -- add parameters and values to args that are not listed in the exclude table
return template; -- args now has all default and live parameters, return working template name
end
--[[--------------------------< W R A P >----------------------------------------------------------------------
Template entry point. Call this function to 'execute' the working template
]]
local function wrap (frame)
local args = {}; -- table of default and live parameters and their values to be passed to the wrapped template
local template; -- the name of the working template
template = _main (frame, args, false); -- get default and live parameters and the name of the working template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
return frame:expandTemplate {title=template, args=args}; -- render the working template
end
--[[--------------------------< L I S T >----------------------------------------------------------------------
Template entry point. Call this function to 'display' the source for the working template. This function added
as a result of a TfD here: Wikipedia:Templates_for_discussion/Log/2018_April_28#Module:PassArguments
This function replaces a similarly named function which was used in {{cite compare}} and {{cite compare2}}
Values in the args table are numerically indexed strings in the form 'name=value'
]]
local function list(frame, do_link)
local args = {}; -- table of default and live parameters and their values to be passed to the listed template
local template; -- the name of the listed template
template = _main (frame, args, true); -- get default and live parameters and the name of the listed template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
if do_link then
template = ('[[%s|%s]]'):format(frame:expandTemplate{ title='Transclude', args = {template} }, template)
end
table.sort(args)
for i = 1, #args do
local stripped = args[i]:match('^' .. i .. '=([^=]*)$')
if stripped then args[i] = stripped else break end
end
return frame:preprocess(table.concat({
'<code style="color:inherit; background:inherit; border:none;">{{',
template,
('<wbr><nowiki>|%s</nowiki>'):rep(#args):format(unpack(args)), '}}</code>'})); -- render the template
end
local function link (frame)
return list(frame, true)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
link = link,
list = list,
wrap = wrap,
};
aa1b56cac4081642637ea7d11fba53513d4335a7
Template:Trim
10
120
255
2021-06-13T14:06:25Z
Canopus >Plastikspork
0
Fix for |=foo bug
wikitext
text/x-wiki
<includeonly>{{safesubst:#if:1|{{{x|{{{1|}}}}}}}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
09ba1a40d9fd41a44a407b144f69a579502fe563
Template:Navbox
10
98
211
2021-06-26T18:05:09Z
Canopus >Trialpears
0
Remove TfD notice as it wouldn't involve any changes to this template.
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
fe9b964401f895918ee4fe078678f1722a3c41ec
Template:Sclass
10
128
271
2021-07-02T16:02:05Z
Canopus >Trappist the monk
0
format name change;
wikitext
text/x-wiki
<includeonly>{{sclass/core|1={{{1}}}|2={{{2}}}|3={{{3|}}}|4={{{4|}}}|5={{{5|}}}|format=sclass}}</includeonly><!--
--><noinclude>{{documentation}}</noinclude>
9e6cac27c57200a375f9fd66187d590a922157d2
Template:Starbox catalog
10
154
323
2021-07-09T10:05:40Z
Canopus >Primefac
0
rmv interwikis
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">[[Star catalogue|Other designations]]</th></tr><!--
--><tr><td colspan="2"><div style="width: 250px;"> {{{names<includeonly>|</includeonly>}}} </div></td></tr><!--
-->{{#if:{{{component1<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component1}}}''': {{{names1}}}</td></tr>}}<!--
-->{{#if:{{{component2<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component2}}}''': {{{names2}}}</td></tr>}}<!--
-->{{#if:{{{component3<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component3}}}''': {{{names3}}}</td></tr>}}<!--
-->{{#if:{{{component4<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component4}}}''': {{{names4}}}</td></tr>}}<noinclude>
|}
{{Documentation}}
</noinclude>
5a833fd635cee397f343a44ca1cb8ea26ae44be3
Module:Pagetype/config
828
60
135
2021-07-10T15:47:32Z
Canopus >Trialpears
0
Book namespace removal will happen within a few days
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Pagetype configuration data --
-- This page holds localisation and configuration data for Module:Pagetype. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
-- This table holds the values to use for "main=true", "user=true", etc. Keys to
-- this table should be namespace parameters that can be used with
-- [[Module:Namespace detect]].
cfg.pagetypes = {
['main'] = 'article',
['user'] = 'user page',
['project'] = 'project page',
['wikipedia'] = 'project page',
['wp'] = 'project page',
['file'] = 'file',
['image'] = 'file',
['mediawiki'] = 'interface page',
['template'] = 'template',
['help'] = 'help page',
['category'] = 'category',
['portal'] = 'portal',
['draft'] = 'draft',
['timedtext'] = 'Timed Text page',
['module'] = 'module',
['topic'] = 'topic',
['gadget'] = 'gadget',
['gadget definition'] = 'gadget definition',
['talk'] = 'talk page',
['special'] = 'special page',
['media'] = 'file',
}
-- This table holds the names of the namespaces to be looked up from
-- cfg.pagetypes by default.
cfg.defaultNamespaces = {
'main',
'file',
'template',
'category',
'module'
}
-- This table holds the names of the namespaces to be looked up from
-- cfg.pagetypes if cfg.defaultnsExtended is set.
cfg.extendedNamespaces = {
'main',
'user',
'project',
'file',
'mediawiki',
'template',
'category',
'help',
'portal',
'module',
'draft'
}
-- The parameter name to set which default namespace values to be looked up from
-- cfg.pagetypes.
cfg.defaultns = 'defaultns'
-- The value of cfg.defaultns to set all namespaces, including talk.
cfg.defaultnsAll = 'all'
-- The value of cfg.defaultns to set the namespaces listed in
-- cfg.extendedNamespaces
cfg.defaultnsExtended = 'extended'
-- The value of cfg.defaultns to set no default namespaces.
cfg.defaultnsNone = 'none'
-- The parameter name to use for disambiguation pages page.
cfg.dab = 'dab'
-- This table holds the different possible aliases for disambiguation-class
-- pages. These should be lower-case.
cfg.dabAliases = {
'disambiguation',
'disambig',
'disamb',
'dab'
}
-- The default value for disambiguation pages.
cfg.dabDefault = 'page'
-- The parameter name to use for N/A-class page.
cfg.na = 'na'
-- This table holds the different possible aliases for N/A-class pages. These
-- should be lower-case.
cfg.naAliases = {'na', 'n/a'}
-- The default value for N/A-class pages.
cfg.naDefault = 'page'
-- The parameter name to use for redirects.
cfg.redirect = 'redirect'
-- The default value to use for redirects.
cfg.redirectDefault = 'redirect'
-- The parameter name for undefined namespaces.
cfg.other = 'other'
-- The value used if the module detects an undefined namespace.
cfg.otherDefault = 'page'
-- The usual suffix denoting a plural.
cfg.plural = 's'
-- This table holds plurals not formed by a simple suffix.
cfg.irregularPlurals = {
["category"] = "categories"
}
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line
e2eb36d6c43611a422bae37947ebeb04b695dcba
Module:Hatnote/styles.css
828
108
231
2021-07-12T19:22:27Z
Canopus >Izno
0
per my talk page
text
text/plain
/* {{pp|small=y}} */
.hatnote {
font-style: italic;
}
/* Limit structure CSS to divs because of [[Module:Hatnote inline]] */
div.hatnote {
/* @noflip */
padding-left: 1.6em;
margin-bottom: 0.5em;
}
.hatnote i {
font-style: normal;
}
/* The templatestyles element inserts a link element before hatnotes.
* TODO: Remove link if/when WMF resolves T200206 */
.hatnote + link + .hatnote {
margin-top: -0.5em;
}
44680ffd6e888866df2cdfa0341af9c7b97da94c
Module:Footnotes
828
102
219
2021-09-14T12:03:42Z
Canopus >Trappist the monk
0
Scribunto
text/plain
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;
--[[--------------------------< A R G S _ D E F A U L T >------------------------------------------------------
a table to specify initial values.
]]
local args_default = {
bracket_left = '',
bracket_right = '',
bracket_year_left = '',
bracket_year_right = '',
postscript = '',
page = '',
pages = '',
location = '',
page_sep = ", p. ",
pages_sep = ", pp. ",
ref = '',
template = 'harv', -- if template name not provided in {{#invoke:}} use this
};
--[[--------------------------< T A R G E T _ C H E C K >------------------------------------------------------
look for anchor_id (CITEREF name-list and year or text from |ref=) in anchor_id_list
the 'no target' error may be suppressed with |ignore-err=yes when target cannot be found because target is inside
a template that wraps another template; 'multiple targets' error may not be suppressed
]]
local function target_check (anchor_id, args)
local namespace = mw.title.getCurrentTitle().namespace;
local anchor_id_list_module = mw.loadData ('Module:Footnotes/anchor_id_list');
local anchor_id_list = anchor_id_list_module.anchor_id_list;
local article_whitelist = anchor_id_list_module.article_whitelist;
local template_list = anchor_id_list_module.template_list;
local whitelist_module = mw.loadData ('Module:Footnotes/whitelist');
local whitelist = whitelist_module.whitelist;
local special_patterns = whitelist_module.special_patterns;
local DNB_special_patterns = whitelist_module.DNB_special_patterns;
local DNB_template_names = whitelist_module.DNB_template_names;
if 10 == namespace then
return ''; -- automatic form of |no-tracking=yes; TODO: is this too broad?
end
local tally = anchor_id_list[anchor_id]; -- nil when anchor_id not in list; else a tally
local msg;
local category;
if not tally then
if args.ignore then
return ''; -- if ignore is true then no message, no category
end
if article_whitelist and article_whitelist[anchor_id] then -- if an article-local whitelist and anchor ID is in it
return ''; -- done
end
local wl_anchor_id = anchor_id; -- copy to be modified to index into the whitelist
if args.year then -- for anchor IDs created by this template (not in |ref=) that have a date
if args.year:match ('%d%l$') or -- use the date value to determine if we should remove the disambiguator
args.year:match ('n%.d%.%l$') or
args.year:match ('nd%l$') then
wl_anchor_id = wl_anchor_id:gsub ('%l$', ''); -- remove the disambiguator
end
end
local t_tbl = whitelist[wl_anchor_id]; -- get list of templates associated with this anchor ID
if t_tbl then -- when anchor ID not whitelisted t_tbl is nil
for _, t in ipairs (t_tbl) do -- spin through the list of templates associated with this anchor ID
if template_list[t] then -- if associated template is found in the list of templates in the article
return ''; -- anchor ID is whitlisted and article has matching template so no error
end
end
end
for _, pattern in ipairs (special_patterns) do -- spin through the spcial patterns and try to match
if anchor_id:match (pattern) then
return '';
end
end
for _, dnb_t in ipairs (DNB_template_names or {}) do -- getting desparate now, are there any DNB templates? DNB_template_names may be nil; empty table prevents script error
if template_list[dnb_t] then -- if the article has this DNB template
for _, pattern in ipairs (DNB_special_patterns) do -- spin through the DNB-specifiec wildcard patterns
if anchor_id:match (pattern) then -- and attempt a match
return ''; -- found a match
end
end
end
end
msg = 'no target: ' .. anchor_id; -- anchor_id not found
category = '[[Category:Harv and Sfn no-target errors]]';
elseif 1 < tally then
msg = 'multiple targets (' .. tally .. '×): ' .. anchor_id; -- more than one anchor_id in this article
category = 0 == namespace and '[[Category:Harv and Sfn multiple-target errors]]' or ''; -- only categorize in article space
return '<span class="error harv-error" style="display: inline; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category;
end
-- category = 0 == namespace and '[[Category:Harv and Sfn template errors]]' or ''; -- only categorize in article space
category = 0 == namespace and category or ''; -- only categorize in article space
--use this version to show error messages
-- return msg and '<span class="error harv-error" style="display: inline; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category or '';
--use this version to hide error messages
return msg and '<span class="error harv-error" style="display: none; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category or '';
end
--[[--------------------------< I S _ Y E A R >----------------------------------------------------------------
evaluates param to see if it is one of these forms with or without lowercase letter disambiguator:
YYYY
n.d.
nd
c. YYYY
YYYY–YYYY (separator is endash)
YYYY–YY (separator is endash)
return true when param has a recognized form; false else
]]
local patterns_date= {
'^%d%d%d%d?%l?$',
'^n%.d%.%l?$',
'^nd%l?$',
'^c%. %d%d%d%d?%l?$',
'^%d%d%d%d–%d%d%d%d%l?$',
'^%d%d%d%d–%d%d%l?$',
}
local function is_year (param, args)
args.year = ''; -- used for harv error;
for _, pattern in ipairs (patterns_date) do
if mw.ustring.match (param, pattern) then
args.year = param; -- used for harv error;
return true;
end
end
end
--[[--------------------------< C O R E >----------------------------------------------------------------------
returns an anchor link (CITEREF) formed from one to four author names, year, and insource location (|p=, |pp=, loc=)
]]
local function core( args )
local result;
local err_msg = ''
if args.P5 ~= '' then
if is_year (args.P5, args) then
result = table.concat ({args.P1, ' et al. ', args.bracket_year_left, args.P5, args.bracket_year_right});
else
args.P5 = ''; -- when P5 not a year don't include in anchor
result = table.concat ({args.P1, ' et al.'}); -- and don't render it
end
elseif args.P4 ~= '' then
if is_year (args.P4, args) then
result = table.concat ({args.P1, ', ', args.P2, ' & ', args.P3, ' ', args.bracket_year_left, args.P4, args.bracket_year_right}); -- three names and a year
else
result = table.concat ({args.P1, ' et al.'}); -- four names
end
elseif args.P3 ~= '' then
if is_year (args.P3, args) then
result = table.concat ({args.P1, ' & ', args.P2, ' ', args.bracket_year_left, args.P3, args.bracket_year_right}); -- two names and a year
else
result = table.concat ({args.P1, ', ', args.P2, ' ', ' & ', args.P3}); -- three names
end
elseif args.P2 ~= '' then
if is_year (args.P2, args) then
result = table.concat ({args.P1, ' ', args.bracket_year_left, args.P2, args.bracket_year_right}); -- one name and year
else
result = table.concat ({args.P1, ' & ', args.P2}); -- two names
end
else
result = args.P1; -- one name
end
-- when author-date result ends with a dot (typically when the last positional parameter holds 'n.d.')
-- and when no in-source location (no |p=, |pp=, or |loc=)
-- and when the first or only character in args.postscript is a dot
-- remove the author-date result trailing dot
-- the author-date result trailing dot will be replaced later with the content of args.postscript (usually a dot)
if ('.' == result:sub(-1)) and ('.' == args.postscript:sub(1)) and ('' == args.page) and ('' == args.pages) and ('' == args.location) then
result = result:gsub ('%.$', '');
end
if args.ref ~= 'none' then
local anchor_id;
if args.ref ~= '' then
anchor_id = mw.uri.anchorEncode (args.ref);
err_msg = target_check (anchor_id, args);
result = table.concat ({'[[#', anchor_id, '|', result, ']]'});
else
anchor_id = mw.uri.anchorEncode (table.concat ({'CITEREF', args.P1, args.P2, args.P3, args.P4, args.P5}));
err_msg = target_check (anchor_id, args);
result = table.concat ({'[[#', anchor_id, '|', result, ']]'});
end
end
if args.page ~= '' then
result = table.concat ({result, args.page_sep, args.page});
elseif args.pages ~= ''then
result = table.concat ({result, args.pages_sep, args.pages});
end
if args.location ~= '' then
result = table.concat ({result, ', ', args.location});
end
result = table.concat ({args.bracket_left, result, args.bracket_right, args.postscript}):gsub ('%s+', ' '); -- strip redundant spaces
return result .. err_msg;
end
--[[--------------------------< H Y P H E N _ T O _ D A S H >--------------------------------------------------
Converts a hyphen to a dash under certain conditions. The hyphen must separate
like items; unlike items are returned unmodified. These forms are modified:
letter - letter (A - B)
digit - digit (4-5)
digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
letterdigit - letterdigit (A1-A5) (an optional separator between letter and
digit is supported – a.1-a.5 or a-1-a-5)
digitletter - digitletter (5a - 5d) (an optional separator between letter and
digit is supported – 5.a-5.d or 5-a-5-d)
any other forms are returned unmodified.
str may be a comma- or semicolon-separated list
This code copied from Module:Citation/CS1. The only modification is to require Module:Citation/CS1/Utilities
so that it has access to the functions is_set() and has_accept_as_written()
]]
local function hyphen_to_dash( str )
local utilities = require ('Module:Citation/CS1/Utilities'); -- only modification so that this function has access to is_set() and has_accept_as_written()
if not utilities.is_set (str) then
return str;
end
local accept; -- Boolean
str = str:gsub ('&[nm]dash;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace HTML numeric entity with hyphen character
str = str:gsub (' ', ' '); -- replace entity with generic keyboard space character
local out = {};
local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any
for _, item in ipairs (list) do -- for each item in the list
item, accept = utilities.has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item
if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators
if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit)
item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter)
item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit
item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit
item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter
item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters
else
item = mw.ustring.gsub (item, '%s*[–—]%s*', '–'); -- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace
end
end
table.insert (out, item); -- add the (possibly modified) item to the output table
end
local temp_str = ''; -- concatenate the output table into a comma separated string
temp_str, accept = utilities.has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out
if accept then
temp_str = utilities.has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value
return temp_str;
else
return temp_str; -- else, return assembled temp_str
end
end
--[[--------------------------< A R G S _ F E T C H >---------------------------------------------------------
Because all of the templates share a common set of parameters, a single common function to fetch those parameters
from frame and parent frame.
]]
local function args_fetch (frame, ps)
local args = args_default; -- create a copy of the default table
local pframe = frame:getParent(); -- point to the template's parameter table
for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any
args[k] = v;
end
args.postscript = pframe.args.postscript or pframe.args.ps or ps;
if 'none' == args.postscript then
args.postscript = '';
end
args.page = pframe.args.p or pframe.args.page or '';
args.pages = pframe.args.pp or pframe.args.pages or '';
args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
args.location = pframe.args.loc or '';
args.ref = pframe.args.ref or pframe.args.Ref or '';
args.ignore = ('yes' == pframe.args['ignore-false-positive']) or ('yes' == pframe.args['ignore-err']);
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- loop through the five positional parameters and trim if set else empty string
args[v] = (pframe.args[i] and mw.text.trim (pframe.args[i])) or '';
end
if args.P5 and not is_year (args.P5, args) then
local i = 6; -- initialize the indexer to the sixth positional parameter
while pframe.args[i] do -- in case there are too many authors loop through the authors looking for a year
local v = mw.text.trim (pframe.args[i]); -- trim
if is_year (v, args) then -- if a year
args.P5 = v; -- overwrite whatever was in args.P5 with year
break; -- and abandon the search
end
i = i + 1; -- bump the indexer
end
end
return args;
end
--[[--------------------------< H A R V A R D _ C I T A T I O N >----------------------------------------------
common entry point for:
{{harvard citation}} aka {{harv}}
{{Harvard citation no brackets}} aka {{harvnb}}
{{harvcol}}
{{harvcolnb}}
{{harvcoltxt}}
{{Harvard citation text}} aka {{harvtxt}}
{{Harvp}}
Distinguishing features (brackets and page separators) are specified in this module's {{#invoke}} in the respective templates.
]]
local function harvard_citation (frame)
local args = args_fetch (frame, ''); -- get the template and invoke parameters; default postscript is empty string
return core (args);
end
--[[--------------------------< S T R I P _ U R L >------------------------------------------------------------
used by sfn() and sfnm(). This function fixes an issue with reference tooltip gadget where the tooltip is not displayed
when an insource locator (|p=, |pp=, |loc=) has an external wikilink that contains a # character
strip uri-reserved characters from urls in |p=, |pp-, and |loc= parameters The researved characters are:
!#$&'()*+,/:;=?@[]
]]
local function strip_url (pages)
local escaped_uri;
if not pages or ('' == pages) then
return pages;
end
for uri in pages:gmatch ('%[(%a[%w%+%.%-]*://%S+)') do -- for each external link get the uri
escaped_uri = uri:gsub ("([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); -- save a copy with lua pattern characters escaped
uri = uri:gsub ("[!#%$&'%(%)%*%+,/:;=%?@%[%]%.%%]", ''); -- remove reserved characters and '%' because '%20' (space character) is a lua 'invalid capture index'
pages = pages:gsub (escaped_uri, uri, 1); -- replace original uri with the stripped version
end
return pages;
end
--[[--------------------------< S F N >------------------------------------------------------------------------
entry point for {{sfn}} and {{sfnp}}
]]
local function sfn (frame)
local args = args_fetch (frame, '.'); -- get the template and invoke parameters; default postscript is a dot
local result = core (args); -- go make a CITEREF anchor
-- put it all together and then strip redundant spaces
local name = table.concat ({'FOOTNOTE', args.P1, args.P2, args.P3, args.P4, args.P5, strip_url (args.page), strip_url (args.pages), strip_url (args.location)}):gsub ('%s+', ' ');
return frame:extensionTag ({name='ref', args={name=name}, content=result});
end
--[[--------------------------< S F N M >----------------------------------------------------------------------
common entry point for {{sfnm}} and {{sfnmp}}
Distinguishing features (brackets) are specified in this module's {{#invoke}} in the respective templates.
]]
local function sfnm (frame)
local args = args_default; -- create a copy of the default table
local pframe = frame:getParent(); -- point to the template's parameter table
local n = 1; -- index of source; this is the 'n' in na1, ny, etc
local first_pnum = 1; -- first of a pair of positional parameters
local second_pnum = 2; -- second of a pair of positional parameters
local last_ps = 0; -- index of the last source with |nps= set
local last_index = 0; -- index of the last source; these used to determine which of |ps= or |nps= will terminate the whole rendering
local out = {}; -- table to hold rendered sources
local footnote = {'FOOTNOTE'}; -- all author, date, insource location stuff becomes part of the reference's footnote id; added as we go
for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any
args[k] = v;
end
while true do
if not pframe.args[table.concat ({n, 'a1'})] and not pframe.args[first_pnum] then
break; -- no na1 or matching positional parameter so done
end
if pframe.args[table.concat ({n, 'a1'})] then -- does this source use named parameters?
for _, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- initialize for this source
args[v] = '';
end
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- extract author and year parameters for this source
args[v] = pframe.args[table.concat ({n, 'a', i})] or ''; -- attempt to assign author name
if '' == args[v] then -- when there wasn't an author name
args[v] = pframe.args[table.concat ({n, 'y'})] or ''; -- attempt to assign year
break; -- done with author/date for this source
end
end
else -- this source uses positional parameters
args.P1 = mw.text.trim (pframe.args[first_pnum]); -- yes, only one author supported
args.P2 = (pframe.args[second_pnum] and mw.text.trim (pframe.args[second_pnum])) or ''; -- when positional author, year must also be positional
for _, v in ipairs ({'P3', 'P4', 'P5'}) do -- blank the rest of these for this source
args[v] = '';
end
first_pnum = first_pnum + 2; -- source must use positional author and positional year
second_pnum = first_pnum + 1; -- bump these for possible next positional source
end
args.postscript = pframe.args[table.concat ({n, 'ps'})] or '';
if 'none' == args.postscript then -- this for compatibility with other footnote templates; does nothing
args.postscript = '';
end
args.ref = pframe.args[table.concat ({n, 'ref'})] or ''; -- alternate reference for this source
args.page = pframe.args[table.concat ({n, 'p'})] or ''; -- insource locations for this source
args.pages = pframe.args[table.concat ({n, 'pp'})] or '';
args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
args.location = pframe.args[table.concat ({n, 'loc'})] or '';
args.ignore = ('yes' == pframe.args[table.concat ({n, 'ignore-false-positive'})]) or ('yes' == pframe.args[table.concat ({n, 'ignore-err'})]);
table.insert (out, core (args)); -- save the rendering of this source
for k, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- create the FOOTNOTE id
if '' ~= args[v] then
table.insert (footnote, args[v]);
end
end
for k, v in ipairs ({'page', 'pages', 'location'}) do -- these done separately so that we can strip uri-reserved characters from extlinked page numbers
if '' ~= args[v] then
table.insert (footnote, strip_url (args[v]))
end
end
last_index = n; -- flags used to select terminal postscript from nps or from end_ps
if '' ~= args.postscript then
last_ps = n;
end
n = n+1; -- bump for the next one
end
local name = table.concat (footnote):gsub ('%s+', ' '); -- put the footnote together and strip redundant space
args.end_ps = pframe.args.postscript or pframe.args.ps or '.'; -- this is the postscript for the whole not for the individual sources
if 'none' == args.end_ps then -- not an original sfnm parameter value; added for compatibility with other footnote templates
args.end_ps = '';
end
local result = table.concat ({table.concat (out, '; '), (last_index == last_ps) and '' or args.end_ps});
return frame:extensionTag ({name='ref', args={name=name}, content=result});
end
--[[--------------------------< S F N R E F >------------------------------------------------------------------
implements {{sfnref}}
]]
local function sfnref (frame)
local args = getArgs (frame);
local out = {};
for i=1, 5 do -- get the first five args if there are five args
if args[i] then
out[i] = args[i];
else
break; -- less than 5 args break out
end
end
if 5 == #out then -- when we have seen five args there may bemore
local i = 6; -- initialize the indexer to the sixth positional parameter
while args[i] do -- in case there are too many authors loop through the authors looking for a year
if is_year (args[i], args) then -- if a year
out[5] = args[i]; -- overwrite whatever was in args[5] with year
break; -- and abandon the search
end
i = i + 1; -- bump the indexer
end
end
return mw.uri.anchorEncode ('CITEREF' .. table.concat (out));
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
harvard_citation = harvard_citation,
sfn = sfn,
sfnm = sfnm,
sfnref = sfnref,
};
1900e2ea7aff0f4023cd9a8f39ece502cc07e045
Template:ErrorBar2
10
151
317
2021-09-18T19:14:24Z
Canopus >Andrybak
0
move documentation to /doc
wikitext
text/x-wiki
<includeonly>{{#if:{{{2|}}}|{{#ifexpr: abs({{{2}}}) > abs({{{1}}} * {{{3}}})|approx. {{rnd|{{{1}}}|-{{order of magnitude|{{{2}}}}}}}|{{rnd|{{{1}}}|-{{order of magnitude|{{{2}}}}} }} ± {{rnd|{{{2}}}|-{{order of magnitude|{{{2}}}}} }} }} |{{{1}}} }}</includeonly><noinclude>
{{documentation}}
</noinclude>
7d3a83f90aace7dc6b51a308b64364e74e8bc666
Kepler
0
26
54
2021-10-05T05:42:36Z
Johannes Kepler>Prakhar
0
wikitext
text/x-wiki
Johannes Kepler was a German [[astronomer]], [[mathematician]], [[astrologer]], natural philosopher and writer on music.[5] He is a key figure in the 17th-century Scientific Revolution, best known for his laws of planetary motion, and his books Astronomia nova, Harmonice Mundi, and Epitome Astronomiae Copernicanae. These works also provided one of the foundations for [[Isaac Newton]] theory of universal gravitation([[Gravity]]).
{| class="wikitable"
|+Facts
|-
|Born
|27 December 1571
Free Imperial City of Weil der Stadt, Holy Roman Empire
|-
|Died
|15 November 1630 (aged 58)
|-
|Nationality
|German
|-
|Known for
|[[Kepler's laws of planetary motion]]
Kepler conjecture
Rudolphine Tables
|-
|Fields
|[[Astronomy]], [[astrology]], [[mathematics]], natural philosophy
|}
3645e8bbf01a9572c47839bad9c98471c4335cf1
Template:Cite simbad
10
165
345
2021-10-20T19:49:45Z
Canopus >MusikBot II
0
Changed protection settings for "[[Template:Cite simbad]]": [[Wikipedia:High-risk templates|High-risk template or module]]: 3956 transclusions ([[User:MusikBot II/TemplateProtector|more info]]) ([Edit=Require extended confirmed access] (indefinite) [Move=Require extended confirmed access] (indefinite))
wikitext
text/x-wiki
{{cite web
|title={{{title|<noinclude>Title</noinclude>}}}
|url=http://simbad.u-strasbg.fr/simbad/sim-basic?Ident{{=}}{{urlencode:{{{title|HD 20794}}}}}
|work=[[SIMBAD]]
|publisher=[[Centre de données astronomiques de Strasbourg]]
|access-date={{{access-date|{{{accessdate|}}}}}}
|mode={{{mode|}}}
|postscript={{{postscript|}}}
}}<noinclude>
{{documentation}}
</noinclude>
b219ca85a3c3d762999e98b05adb0b273a17f2b5
Template:Cite OED
10
130
275
2021-11-08T19:22:23Z
Canopus >Twinsday
0
link publisher
wikitext
text/x-wiki
{{#invoke:template wrapper|{{#if:{{{_debug|}}}|list|wrap}}|_template=cite dictionary
|_exclude=id, short, term, _debug
|url={{#ifeq:{{{term|{{{1|}}}<!-- -->}}}|<!--not set-->|
|{{#if:{{{id|}}}
|https://www.oed.com/view/Entry/{{{id}}}
|https://oed.com/search?searchType=dictionary&q={{urlencode:{{{term|{{{1|}}}}}}}}
}}
}}
|url-access={{#if:{{{term|}}}{{{1|}}}{{{id|}}}|subscription}}
|title={{{term|{{{1|}}}}}}
|dictionary=[[Oxford English Dictionary]]
|publisher={{#if:{{{short|}}}||[[Oxford University Press]]}}
|edition={{#if:{{{short|}}}||Online}}
|ref={{#if:{{{term|}}}{{{1|}}}{{{id|}}}|{{SfnRef|Reference-OED-{{{term|{{{1|}}}}}}}}}}
}}{{#if:{{{short|}}}| | {{OEDsub|sentence={{#ifeq:{{{mode|cs1}}}|cs1|yes|no}}}}<!---->}}<noinclude>
{{documentation}}
</noinclude>
c4826a4de9a2fb0fb19a568c15f96013d914f71d
Module:Navbar
828
110
235
2021-11-13T05:33:43Z
Canopus >Izno
0
remove unnecessary line
Scribunto
text/plain
local p = {}
local cfg = mw.loadData('Module:Navbar/configuration')
local function get_title_arg(is_collapsible, template)
local title_arg = 1
if is_collapsible then title_arg = 2 end
if template then title_arg = 'template' end
return title_arg
end
local function choose_links(template, args)
-- The show table indicates the default displayed items.
-- view, talk, edit, hist, move, watch
-- TODO: Move to configuration.
local show = {true, true, true, false, false, false}
if template then
show[2] = false
show[3] = false
local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6,
talk = 2, edit = 3, hist = 4, move = 5, watch = 6}
-- TODO: Consider removing TableTools dependency.
for _, v in ipairs(require ('Module:TableTools').compressSparseArray(args)) do
local num = index[v]
if num then show[num] = true end
end
end
local remove_edit_link = args.noedit
if remove_edit_link then show[3] = false end
return show
end
local function add_link(link_description, ul, is_mini, font_style)
local l
if link_description.url then
l = {'[', '', ']'}
else
l = {'[[', '|', ']]'}
end
ul:tag('li')
:addClass('nv-' .. link_description.full)
:wikitext(l[1] .. link_description.link .. l[2])
:tag(is_mini and 'abbr' or 'span')
:attr('title', link_description.html_title)
:cssText(font_style)
:wikitext(is_mini and link_description.mini or link_description.full)
:done()
:wikitext(l[3])
:done()
end
local function make_list(title_text, has_brackets, displayed_links, is_mini, font_style)
local title = mw.title.new(mw.text.trim(title_text), cfg.title_namespace)
if not title then
error(cfg.invalid_title .. title_text)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''
-- TODO: Get link_descriptions and show into the configuration module.
-- link_descriptions should be easier...
local link_descriptions = {
{ ['mini'] = 'v', ['full'] = 'view', ['html_title'] = 'View this template',
['link'] = title.fullText, ['url'] = false },
{ ['mini'] = 't', ['full'] = 'talk', ['html_title'] = 'Discuss this template',
['link'] = talkpage, ['url'] = false },
{ ['mini'] = 'e', ['full'] = 'edit', ['html_title'] = 'Edit this template',
['link'] = title:fullUrl('action=edit'), ['url'] = true },
{ ['mini'] = 'h', ['full'] = 'hist', ['html_title'] = 'History of this template',
['link'] = title:fullUrl('action=history'), ['url'] = true },
{ ['mini'] = 'm', ['full'] = 'move', ['html_title'] = 'Move this template',
['link'] = mw.title.new('Special:Movepage'):fullUrl('target='..title.fullText), ['url'] = true },
{ ['mini'] = 'w', ['full'] = 'watch', ['html_title'] = 'Watch this template',
['link'] = title:fullUrl('action=watch'), ['url'] = true }
}
local ul = mw.html.create('ul')
if has_brackets then
ul:addClass(cfg.classes.brackets)
:cssText(font_style)
end
for i, _ in ipairs(displayed_links) do
if displayed_links[i] then add_link(link_descriptions[i], ul, is_mini, font_style) end
end
return ul:done()
end
function p._navbar(args)
-- TODO: We probably don't need both fontstyle and fontcolor...
local font_style = args.fontstyle
local font_color = args.fontcolor
local is_collapsible = args.collapsible
local is_mini = args.mini
local is_plain = args.plain
local collapsible_class = nil
if is_collapsible then
collapsible_class = cfg.classes.collapsible
if not is_plain then is_mini = 1 end
if font_color then
font_style = (font_style or '') .. '; color: ' .. font_color .. ';'
end
end
local navbar_style = args.style
local div = mw.html.create():tag('div')
div
:addClass(cfg.classes.navbar)
:addClass(cfg.classes.plainlinks)
:addClass(cfg.classes.horizontal_list)
:addClass(collapsible_class) -- we made the determination earlier
:cssText(navbar_style)
if is_mini then div:addClass(cfg.classes.mini) end
local box_text = (args.text or cfg.box_text) .. ' '
-- the concatenated space guarantees the box text is separated
if not (is_mini or is_plain) then
div
:tag('span')
:addClass(cfg.classes.box_text)
:cssText(font_style)
:wikitext(box_text)
end
local template = args.template
local displayed_links = choose_links(template, args)
local has_brackets = args.brackets
local title_arg = get_title_arg(is_collapsible, template)
local title_text = args[title_arg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local list = make_list(title_text, has_brackets, displayed_links, is_mini, font_style)
div:node(list)
if is_collapsible then
local title_text_class
if is_mini then
title_text_class = cfg.classes.collapsible_title_mini
else
title_text_class = cfg.classes.collapsible_title_full
end
div:done()
:tag('div')
:addClass(title_text_class)
:cssText(font_style)
:wikitext(args[1])
end
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = cfg.templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
return p._navbar(require('Module:Arguments').getArgs(frame))
end
return p
a5c8d3a8f8beb18984ea7f145ddbdf88a065d23e
Module:Navbar/configuration
828
111
237
2021-11-13T05:39:10Z
Canopus >Izno
0
well, since I edited the other one...
Scribunto
text/plain
return {
['templatestyles'] = 'Module:Navbar/styles.css',
['box_text'] = 'This box: ', -- default text box when not plain or mini
['title_namespace'] = 'Template', -- namespace to default to for title
['invalid_title'] = 'Invalid title ',
['classes'] = { -- set a line to nil if you don't want it
['navbar'] = 'navbar',
['plainlinks'] = 'plainlinks', -- plainlinks
['horizontal_list'] = 'hlist', -- horizontal list class
['mini'] = 'navbar-mini', -- class indicating small links in the navbar
['this_box'] = 'navbar-boxtext',
['brackets'] = 'navbar-brackets',
-- 'collapsible' is the key for a class to indicate the navbar is
-- setting up the collapsible element in addition to the normal
-- navbar.
['collapsible'] = 'navbar-collapse',
['collapsible_title_mini'] = 'navbar-ct-mini',
['collapsible_title_full'] = 'navbar-ct-full'
}
}
bbf3d86b48a5b40835e8e232ae9821e6bca390ec
Energy
0
25
52
2021-11-20T11:18:31Z
Energy >Prakhar
0
Created page with "Energy of a body is defined as the capacity or ability of the body to do [[Work]]. ==Forms of energy== ===Mechanical energy=== It includes kinetic and potential energy. '''Ki..."
wikitext
text/x-wiki
Energy of a body is defined as the capacity or ability of the body to do [[Work]].
==Forms of energy==
===Mechanical energy===
It includes kinetic and potential energy.
'''Kinetic energy'''
The energy possessed by a body by the virtue of its motion is called kinetic energy. An object in motion has the ability to do work and hence possesses kinetic energy.
Examples of Kinetic Energy
(1) Wind possesses kinetic energy and can run wind mill.
(1) The kinetic energy of flowing water is used to generate electricity.
(ii) A bullet fired from a gun possesses kinetic energy and can penetrate a target.
Formula
Kinetic energy = 1/2 *mv²
Where m = mass and v² = velocity squared
'''Potential energy'''
The energy possessed by a body by the virtue of its position([[displacement]]) or its configuration (shape or size) is called potential energy. An object may have the capacity of doing work as a result of its position in a gravitational([[gravity]]) field, an electric field or a magnetic field. Potential energy may be positive or negative. Potential energy is often referred as stored energy.
Examples of Potential Energy
(1) The heavy ball of a demolition machine has potential energy when it is held at an elevated position.
(i) A stone lying on the ground has no energy so it cannot do any work. If this stone is lifted to the roof of a house, the work has been done in lifting this stone against the force of gravity. This
work gets stored up in the stone in the form of potential energy.
(ii) The water stored at height in a dam has potential energy. If it is allowed to fall, the falling water has the ability to rotate turbine to generate electricity.
(M) A stone resting on the edge of a cliff has potential energy due to its position in the earth's gravitational field. If it falls, the force of gravity which is equal to the stone's weight will act on it until it strikes the ground. The stone's potential energy is equal to the product of its weight and distance it can fall through.
(1) Elastic Potential Energy
The energy possessed by a body due to the change in its shape is called as elastic potential energy. The change in shape of the body can be brought by compressing, stretching or bending. For this change, some work has to be done. This work gets stored in the form of elastic potential energy. When this deformed body is released it regains its original position and potential energy is given out in some other form of energy.
(B)
"The gravitational potential energy of an object at a point above the ground is defined as the as the work done is raising it from the ground to that point against gravity without any [[acceleration]]"
Formula
Work (w) = Mass (M) * Gravity (g) * Displacement (S) or w = mg * s
Potential energy = mg * h
===Heat energy===
Heat can be defined as the form of energy that is transferred between two points due to the presence of a [[temperature]] difference between the two points. When water boils, it changes to steam. The steam possesses heat energy because it has the ability to do work such as to run stear engines, turbine etc. The heat produced by the burning of petrol in a car engine provides the energy needed to run the car.
===Nuclear energy===
The energy stored in the nucleus of an atom is called nuclear energy. The energy stored in the nuclei of atoms can be obtained by carrying out two types of nuclear reactions called nuclear fusion and nuclear fission.
c9ad0cf3f0a960b707ef98e06b087a2ec4630142
Template:Authority control
10
90
195
2021-11-22T21:18:20Z
Canopus >MSGJ
0
add extralist to list of recognised parameters
wikitext
text/x-wiki
{{#invoke:Authority control|authorityControl}}<noinclude>{{Documentation}}</noinclude><includeonly><noinclude>
</noinclude>{{#switch:{{NAMESPACE}}||{{ns:14}}=<noinclude> Only articles and categories.
</noinclude>{{#invoke:Check for unknown parameters|check|arts|state|extralist|ignoreblank=1|showblankpositional=1|unknown=[[Category:Pages using authority control with parameters|_VALUE_]]|preview=Page using [[Template:Authority control]] with "_VALUE_", please move this to Wikidata if possible}}
}}</includeonly>
e90b2d4067a752dad843f562fc9e4114bf560c8a
Module:IPAc-en/phonemes
828
84
183
2021-11-23T07:28:18Z
Canopus >Nardog
0
Reverted 1 edit by [[Special:Contributions/Kwamikagami|Kwamikagami]] ([[User talk:Kwamikagami|talk]]): Please seek consensus first
Scribunto
text/plain
-- This module contains phoneme data for [[Module:IPAc-en]].
return {
-- CONSONANTS
{
code = "b",
label = "b",
tooltip = "'b' in 'buy'",
},
{
code = "d",
label = "d",
tooltip = "'d' in 'dye'",
},
{
code = "dj",
aliases = {"dy", "dʲ"},
label = "dj",
tooltip = "/dj/: 'd' in 'dew'",
},
{
code = "dʒ",
aliases = {"dZ", "ʤ"},
label = "dʒ",
tooltip = "/dʒ/: 'j' in 'jam'",
},
{
code = "ð",
aliases = {"D"},
label = "ð",
tooltip = "/ð/: 'th' in 'this'",
},
{
code = "f",
label = "f",
tooltip = "'f' in 'find'",
},
{
code = "ɡ",
aliases = {"g"},
label = "ɡ",
tooltip = "/ɡ/: 'g' in 'guy'",
},
{
code = "h",
label = "h",
tooltip = "'h' in 'hi'",
},
{
code = "hw",
aliases = {"ʍ"},
label = "hw",
tooltip = "/hw/: 'wh' in 'why'",
},
{
code = "j",
aliases = {"y"},
label = "j",
tooltip = "/j/: 'y' in 'yes'",
},
{
code = "k",
label = "k",
tooltip = "'k' in 'kind'",
},
{
code = "l",
label = "l",
tooltip = "'l' in 'lie'",
},
{
code = "lj",
aliases = {"ly", "lʲ"},
label = "lj",
tooltip = "/lj/: 'l' in 'lute'",
},
{
code = "m",
label = "m",
tooltip = "'m' in 'my'",
},
{
code = "n",
label = "n",
tooltip = "'n' in 'nigh'",
},
{
code = "nj",
aliases = {"ny", "nʲ"},
label = "nj",
tooltip = "/nj/: 'n' in 'new'",
},
{
code = "ŋ",
aliases = {"N", "ng"},
label = "ŋ",
tooltip = "/ŋ/: 'ng' in 'sing'",
},
{
code = "p",
label = "p",
tooltip = "'p' in 'pie'",
},
{
code = "r",
aliases = {"ɹ", "ɻ"},
label = "r",
tooltip = "'r' in 'rye'",
},
{
code = "s",
label = "s",
tooltip = "'s' in 'sigh'",
},
{
code = "sj",
aliases = {"sy", "sʲ"},
label = "sj",
tooltip = "/sj/: 's' in 'consume'",
},
{
code = "ʃ",
aliases = {"S", "sh"},
label = "ʃ",
tooltip = "/ʃ/: 'sh' in 'shy'",
},
{
code = "t",
label = "t",
tooltip = "'t' in 'tie'",
},
{
code = "tj",
aliases = {"ty", "tʲ"},
label = "tj",
tooltip = "/tj/: 't' in 'tune'",
},
{
code = "tʃ",
aliases = {"tS", "ʧ", "ch"},
label = "tʃ",
tooltip = "/tʃ/: 'ch' in 'China'",
},
{
code = "θ",
aliases = {"T"},
label = "θ",
tooltip = "/θ/: 'th' in 'thigh'",
},
{
code = "θj",
aliases = {"θy", "θʲ"},
label = "θj",
tooltip = "/θj/: 'th' in 'enthuse'",
},
{
code = "v",
label = "v",
tooltip = "'v' in 'vie'",
},
{
code = "w",
label = "w",
tooltip = "'w' in 'wind'",
},
{
code = "z",
label = "z",
tooltip = "'z' in 'zoom'",
},
{
code = "zj",
aliases = {"zy", "zʲ"},
label = "zj",
tooltip = "/zj/: 'Z' in 'Zeus'",
},
{
code = "ʒ",
aliases = {"Z", "zh"},
label = "ʒ",
tooltip = "/ʒ/: 's' in 'pleasure'",
},
-- VOWELS
{
code = "ɑː",
aliases = {"A:", "ɑ:", "aː", "a:"},
label = "ɑː",
tooltip = "/ɑː/: 'a' in 'father'",
},
{
code = "ɑːr",
aliases = {"ɑɹ", "aːr", "a:r", "ɑ:r", "ɑr"},
label = "ɑːr",
tooltip = "/ɑːr/: 'ar' in 'far'",
},
{
code = "ɒ",
aliases = {"Q"},
label = "ɒ",
tooltip = "/ɒ/: 'o' in 'body'",
},
{
code = "ɒr",
aliases = {"Qr"},
label = "ɒr",
tooltip = "/ɒr/: 'or' in 'moral'",
},
{
code = "æ",
aliases = {"ae", "{"},
label = "æ",
tooltip = "/æ/: 'a' in 'bad'",
},
{
code = "ær",
aliases = {"aer", "&r", "æɹ"},
label = "ær",
tooltip = "/ær/: 'arr' in 'marry'",
},
{
code = "aɪ",
aliases = {"ai", "aI"},
label = "aɪ",
tooltip = "/aɪ/: 'i' in 'tide'",
},
{
code = "aɪər",
aliases = {"aɪr", "aIr", "aɪə"},
label = "aɪər",
tooltip = "/aɪər/: 'ire' in 'fire'",
},
{
code = "aʊ",
aliases = {"au", "aU"},
label = "aʊ",
tooltip = "/aʊ/: 'ou' in 'mouth'",
},
{
code = "aʊər",
aliases = {"aʊr", "aUr", "aʊə", "aur"},
label = "aʊər",
tooltip = "/aʊər/: 'our' in 'hour'",
},
{
code = "ɛ",
aliases = {"E"},
label = "ɛ",
tooltip = "/ɛ/: 'e' in 'dress'",
},
{
code = "ɛr",
aliases = {"Er"},
label = "ɛr",
tooltip = "/ɛr/: 'err' in 'merry'",
},
{
code = "eɪ",
aliases = {"ei", "eI", "eː", "e:"},
label = "eɪ",
tooltip = "/eɪ/: 'a' in 'face'",
},
{
code = "ɛər",
aliases = {"eir", "eIr", "e@r", "E@r", "ɛɪɹ", "eɪr", "eːr", "e:r", "ɛəɹ", "ɛə", "ɛːr", "ɛ:r", "ɛː", "ɛ:", "E:", "E:r"},
label = "ɛər",
tooltip = "/ɛər/: 'are' in 'bare'",
},
{
code = "ɛəˈr",
aliases = {"ɛə'r", "eəˈr", "eə'r", "e@'r", "E@'r", "ɛːˈr", "E:'r"},
label = "ɛəˈr",
tooltip = "/ɛəˈr/: 'ere' in 'thereof'",
},
{
code = "ɛəˌr",
aliases = {"ɛə,r", "eəˌr", "eə,r", "E@,r", "E@%r", "e@,r", "e@%r", "ɛːˌr", "E:,r", "E:%r"},
label = "ɛəˌr",
tooltip = "/ɛəˌr/: 'ere' in 'thereof'",
},
{
code = "ɪ",
aliases = {"I", "ᵻ"},
label = "ɪ",
tooltip = "/ɪ/: 'i' in 'kit'",
},
{
code = "ɪr",
label = "ɪr",
tooltip = "/ɪr/: 'irr' in 'mirror'",
},
{
code = "iː",
aliases = {"i:"},
label = "iː",
tooltip = "/iː/: 'ee' in 'fleece'",
},
{
code = "ɪər",
aliases = {"i:r", "iːr", "I@r", "i@r", "ɪəɹ", "iːɹ", "ɪə"},
label = "ɪər",
tooltip = "/ɪər/: 'ear' in 'near'",
},
{
code = "ɪəˈr",
aliases = {"ɪə'r", "I@'r"},
label = "ɪəˈr",
tooltip = "/ɪəˈr/: 'er' in 'spheroidal'",
},
{
code = "ɪəˌr",
aliases = {"ɪə,r", "I@,r", "I@%r"},
label = "ɪəˌr",
tooltip = "/ɪəˌr/: 'er' in 'spheroidal'",
},
{
code = "oʊ",
aliases = {"o:", "oː", "ou", "oU", "@u", "@U", "əʊ", "əu", "oʊ-"},
label = "oʊ",
tooltip = "/oʊ/: 'o' in 'code'",
},
{
code = "ɔː",
aliases = {"O", "O:", "ɔ:", "ɒː", "Q:"},
label = "ɔː",
tooltip = "/ɔː/: 'au' in 'fraud'",
},
{
code = "ɔːr",
aliases = {"Or", "ɔɹ", "ɔ(r)", "ɔr", "ɔər", "oUr", "ɔəɹ", "ɔʊɹ", "oʊɹ", "oʊr", "oːr", "o:r", "ɔə", "ɔə(r)"},
label = "ɔːr",
tooltip = "/ɔːr/: 'ar' in 'war'",
},
{
code = "ɔɪ",
aliases = {"oj", "ɔj", "oi", "oɪ", "ɔi", "OI", "oy"},
label = "ɔɪ",
tooltip = "/ɔɪ/: 'oi' in 'choice'",
},
{
code = "ɔɪər",
aliases = {"ɔɪr", "oyr", "ɔɪə"},
label = "ɔɪər",
tooltip = "/ɔɪər/: 'oir' in 'coir'",
},
{
code = "ʊ",
aliases = {"U", "ᵿ"},
label = "ʊ",
tooltip = "/ʊ/: 'u' in 'push'",
},
{
code = "ʊr",
aliases = {"Ur"},
label = "ʊr",
tooltip = "/ʊr/: 'our' in 'courier'",
},
{
code = "uː",
aliases = {"u:"},
label = "uː",
tooltip = "/uː/: 'oo' in 'goose'",
},
{
code = "ʊər",
aliases = {"u:r", "uːr", "u@r", "U@r", "ʊəɹ", "ʊə"},
label = "ʊər",
tooltip = "/ʊər/: 'our' in 'tour'",
},
{
code = "ʊəˈr",
aliases = {"ʊə'r", "U@'r"},
label = "ʊəˈr",
tooltip = "/ʊəˈr/: 'ur' in 'plurality'",
},
{
code = "ʊəˌr",
aliases = {"ʊə,r", "U@,r", "U@%r"},
label = "ʊəˌr",
tooltip = "/ʊəˌr/: 'ur' in 'plurality'",
},
{
code = "ʌ",
aliases = {"V"},
label = "ʌ",
tooltip = "/ʌ/: 'u' in 'cut'",
},
{
code = "ʌr",
aliases = {"Vr", "ʌɹ"},
label = "ʌr",
tooltip = "/ʌr/: 'urr' in 'hurry'",
},
{
code = "ɜːr",
aliases = {"ɝː", "ɝ", "3r", "3:r", "əːr", "@:r", "ɜɹ", "ɜ(r)", "ɜr"},
label = "ɜːr",
tooltip = "/ɜːr/: 'ur' in 'fur'",
},
{
code = "ə",
aliases = {"@"},
label = "ə",
tooltip = "/ə/: 'a' in 'about'",
},
-- SYLLABIC CONSONANTS
{
code = "ər",
aliases = {"ɚ", "@r", "əɹ", "ə(r)"},
label = "ər",
tooltip = "/ər/: 'er' in 'letter'",
},
{
code = "əl",
aliases = {"@l", "ᵊl", "l̩"},
label = "əl",
tooltip = "/əl/: 'le' in 'bottle'",
},
{
code = "ən",
aliases = {"@n", "ᵊn", "n̩"},
label = "ən",
tooltip = "/ən/: 'on' in 'button'",
},
{
code = "əm",
aliases = {"@m", "ᵊm", "m̩"},
label = "əm",
tooltip = "/əm/: 'm' in 'rhythm'",
},
-- ARCHIPHONEMES
{
code = "i",
label = "i",
tooltip = "/i/: 'y' in 'happy'",
},
{
code = "u",
label = "u",
tooltip = "/u/: 'u' in 'influence'",
},
-- MARGINAL SEGMENTS
{
code = "x",
label = "x",
aliases = {"kh"},
tooltip = "/x/: 'ch' in 'loch'",
},
{
code = "ʔ",
aliases = {"?"},
label = "ʔ",
tooltip = "/ʔ/: the catch in 'uh-oh'",
},
{
code = "ɒ̃",
aliases = {"ɑ̃", "ɒ~", "ɑ~", "Q~"},
label = "ɒ̃",
tooltip = "/ɒ̃/: nasal 'an' in 'vin blanc'",
},
{
code = "æ̃",
aliases = {"ae~", "{~", "ã", "a~"},
label = "æ̃",
tooltip = "/æ̃/: nasal 'in' in 'vin blanc'",
},
{
code = "ɜː",
aliases = {"3", "3:", "ɜ:", "ɜ", "əː", "@:"},
label = "ɜː",
tooltip = "/ɜː/: r-less 'ur' in 'nurse'",
},
-- SUPRASEGMENTALS
{
code = "ˈ",
aliases = {"'", '"'},
label = "ˈ",
tooltip = "/ˈ/: primary stress follows",
},
{
code = "ˌ",
aliases = {",", "%"},
label = "ˌ",
tooltip = "/ˌ/: secondary stress follows",
},
{
code = ".",
aliases = {"·"},
label = ".",
tooltip = "/./: syllable break",
},
{
code = "#",
label = "#",
tooltip = "/#/: morpheme break",
},
{
code = "!",
label = "|",
tooltip = "/|/: prosodic break (minor)",
},
{
code = "!!",
aliases = {"‖"},
label = "‖",
tooltip = "/‖/: prosodic break (major)",
},
-- SEPARATORS
-- Tables without tooltip text are used as word separators. In addition to
-- not having any tooltip text in the template output, they are not
-- underlined.
{
code = "_",
label = "<span class=\"wrap\"> </span>",
},
{
code = "nbsp",
aliases = {" "},
label = " ",
},
{
code = ",_",
label = ",<span class=\"wrap\"> </span>",
},
{
code = "-",
aliases = {"–"},
label = "-",
},
{
code = "(",
label = "(",
},
{
code = ")",
label = ")",
},
-- This is useful for highly variable words in place names, which are not
-- important to transcribe.
{
code = "...",
label = " ...<span class=\"wrap\"> </span>",
},
-- Obsolete combinations, kept for compatibility
{
code = "juː",
label = "juː",
tooltip = "/juː/: 'u' in 'cute'",
},
{
code = "jʊər",
label = "jʊər",
tooltip = "/jʊər/: 'ure' in 'cure'",
},
}
edb55389474ac8485fc15b3386eebeb0c44b7263
Module:Lang-zh
828
150
315
2021-12-05T17:08:57Z
Canopus >Pppery
0
Update per edit request
Scribunto
text/plain
require('Module:No globals')
local p = {}
-- articles in which traditional Chinese preceeds simplified Chinese
local t1st = {
["228 Incident"] = true,
["Chinese calendar"] = true,
["Lippo Centre, Hong Kong"] = true,
["Republic of China"] = true,
["Republic of China at the 1924 Summer Olympics"] = true,
["Taiwan"] = true,
["Taiwan (island)"] = true,
["Taiwan Province"] = true,
["Wei Boyang"] = true,
}
-- the labels for each part
local labels = {
["c"] = "Chinese",
["s"] = "simplified Chinese",
["t"] = "traditional Chinese",
["p"] = "pinyin",
["tp"] = "Tongyong Pinyin",
["w"] = "Wade–Giles",
["j"] = "Jyutping",
["cy"] = "Cantonese Yale",
["sl"] = "Sidney Lau",
["poj"] = "Pe̍h-ōe-jī",
["zhu"] = "Zhuyin Fuhao",
["l"] = "lit.",
["tr"] = "trans.",
}
-- article titles for wikilinks for each part
local wlinks = {
["c"] = "Chinese language",
["s"] = "simplified Chinese characters",
["t"] = "traditional Chinese characters",
["p"] = "pinyin",
["tp"] = "Tongyong Pinyin",
["w"] = "Wade–Giles",
["j"] = "Jyutping",
["cy"] = "Yale romanization of Cantonese",
["sl"] = "Sidney Lau romanisation",
["poj"] = "Pe̍h-ōe-jī",
["zhu"] = "Bopomofo",
["l"] = "Literal translation",
["tr"] = "Translation",
}
-- for those parts which are to be treated as languages their ISO code
local ISOlang = {
["c"] = "zh",
["t"] = "zh-Hant",
["s"] = "zh-Hans",
["p"] = "zh-Latn-pinyin",
["tp"] = "zh-Latn",
["w"] = "zh-Latn-wadegile",
["j"] = "yue-Latn-jyutping",
["cy"] = "yue-Latn",
["sl"] = "yue-Latn",
["poj"] = "nan-Latn",
["zhu"] = "zh-Bopo",
}
local italic = {
["p"] = true,
["tp"] = true,
["w"] = true,
["j"] = true,
["cy"] = true,
["sl"] = true,
["poj"] = true,
}
local superscript = {
["w"] = true,
["sl"] = true,
}
-- Categories for different kinds of Chinese text
local cats = {
["c"] = "[[Category:Articles containing Chinese-language text]]",
["s"] = "[[Category:Articles containing simplified Chinese-language text]]",
["t"] = "[[Category:Articles containing traditional Chinese-language text]]",
}
function p.Zh(frame)
-- load arguments module to simplify handling of args
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
return p._Zh(args)
end
function p._Zh(args)
local uselinks = not (args["links"] == "no") -- whether to add links
local uselabels = not (args["labels"] == "no") -- whether to have labels
local capfirst = args["scase"] ~= nil
local t1 = false -- whether traditional Chinese characters go first
local j1 = false -- whether Cantonese Romanisations go first
local testChar
if (args["first"]) then
for testChar in mw.ustring.gmatch(args["first"], "%a+") do
if (testChar == "t") then
t1 = true
end
if (testChar == "j") then
j1 = true
end
end
end
if (t1 == false) then
local title = mw.title.getCurrentTitle()
t1 = t1st[title.text] == true
end
-- based on setting/preference specify order
local orderlist = {"c", "s", "t", "p", "tp", "w", "j", "cy", "sl", "poj", "zhu", "l", "tr"}
if (t1) then
orderlist[2] = "t"
orderlist[3] = "s"
end
if (j1) then
orderlist[4] = "j"
orderlist[5] = "cy"
orderlist[6] = "sl"
orderlist[7] = "p"
orderlist[8] = "tp"
orderlist[9] = "w"
end
-- rename rules. Rules to change parameters and labels based on other parameters
if args["hp"] then
-- hp an alias for p ([hanyu] pinyin)
args["p"] = args["hp"]
end
if args["tp"] then
-- if also Tongyu pinyin use full name for Hanyu pinyin
labels["p"] = "Hanyu Pinyin"
end
if (args["s"] and args["s"] == args["t"]) then
-- Treat simplified + traditional as Chinese if they're the same
args["c"] = args["s"]
args["s"] = nil
args["t"] = nil
elseif (not (args["s"] and args["t"])) then
-- use short label if only one of simplified and traditional
labels["s"] = labels["c"]
labels["t"] = labels["c"]
end
local body = "" -- the output string
local params -- for creating HTML spans
local label -- the label, i.e. the bit preceeding the supplied text
local val -- the supplied text
-- go through all possible fields in loop, adding them to the output
for i, part in ipairs(orderlist) do
if (args[part]) then
-- build label
label = ""
if (uselabels) then
label = labels[part]
if (capfirst) then
label = mw.language.getContentLanguage():ucfirst(label)
capfirst = false
end
if (uselinks) then
label = "[[" .. wlinks[part] .. "|" .. label .. "]]"
end
if (labels[part] ~= "lit.") then
label = label .. ":"
else
label = "<small>" .. label .. "</small>"
end
label = label .. " "
end
-- build value
val = args[part]
if (cats[part]) and mw.title.getCurrentTitle().namespace == 0 then
-- if has associated category AND current page in article namespace, add category
val = cats[part] .. val
end
if (ISOlang[part]) then
-- add span for language if needed
params = {["lang"] = ISOlang[part]}
val = mw.text.tag({name="span",attrs=params, content=val})
elseif ((part == "l") or (part == "tr")) then
-- put literals in quotes
val = "'" .. val .. "'"
end
if (italic[part]) then
-- italicise
val = "<i>" .. val .. "</i>"
end
if string.match(val, "</?sup>") then val = val.."[[Category:Pages using template Zh with sup tags]]" end
if (superscript[part]) then
-- superscript
val = val:gsub("(%d)", "<sup>%1</sup>"):gsub("(%d)</sup>%*<sup>(%d)", "%1*%2"):gsub("<sup><sup>([%d%*]+)</sup></sup>", "<sup>%1</sup>")
end
-- add both to body
body = body .. label .. val .. "; "
end
end
if (body > "") then -- check for empty string
return string.sub(body, 1, -3) -- chop off final semicolon and space
else --no named parameters; see if there's a first parameter, ignoring its name
if (args[1]) then
-- if there is treat it as Chinese
label = ""
if (uselabels) then
label = labels["c"]
if (uselinks) then
label = "[[" .. wlinks["c"] .. "|" .. label .. "]]"
end
label = label .. ": "
end
-- default to show links and labels as no options given
if mw.title.getCurrentTitle().namespace == 0 then
-- if current page in article namespace
val = cats["c"] .. args[1]
else
val = args[1]
end
params = {["lang"] = ISOlang["c"]}
val = mw.text.tag({name="span",attrs=params, content=val})
return label .. val
end
return ""
end
end
return p
784d83ce2141b8e5828575b09c81e5f62a637998
Template:Main other
10
66
147
2021-12-10T16:08:06Z
Canopus >Xaosflux
0
<!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
wikitext
text/x-wiki
{{#switch:
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{lc: {{{demospace}}} }} <!--Use lower case "demospace"-->
| {{#ifeq:{{NAMESPACE}}|{{ns:0}}
| main
| other
}}
}}
| main = {{{1|}}}
| other
| #default = {{{2|}}}
}}<noinclude>
{{documentation}}
<!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
</noinclude>
86ad907ffeea3cc545159e00cd1f2d6433946450
Module:Footnotes/anchor id list
828
103
221
2021-12-20T18:02:30Z
Canopus >Trappist the monk
0
Scribunto
text/plain
require('Module:No globals');
local data = mw.loadData ('Module:Footnotes/anchor id list/data');
local whitelist = mw.loadData ('Module:Footnotes/whitelist');
local Lang_obj = mw.language.getContentLanguage(); -- used by template_list_add() to uppercase first letter of template name TODO: better way to do that?
local redirects_date = {
['date'] = true,
['datetomos'] = true,
['formatdate'] = true,
['isotodmymdy'] = true,
['isotomos'] = true,
}
local redirects_patent = { -- special case cs1-like templates because uses different parameters for name and date in anchor ID
['Cite patent'] = true,
['Citeref patent'] = true,
['Ref patent'] = true,
}
local redirects_sfnref = {
['sfnref'] = true,
['harvid'] = true,
}
local aliases_author = { -- these use pseudo-patterns in the same way as cs1|2; '#' represents 1 or more enumerator digits
'last#',
'author#',
'surname#',
'author-last#',
'author#-last',
'subject#',
'host#',
}
local aliases_contributor = {
'contributor#',
'contributor-last#',
'contributor#-last',
'contributor-surname#',
'contributor#-surname',
}
local aliases_editor = {
'editor#',
'editor-last#',
'editor#-last',
'editor-surname#',
'editor#-surname',
}
local aliases_harvc_author = {
'last#',
'author#',
}
local aliases_inventor = { -- cite patent
'inventor#',
'inventor-last#',
'inventor#-last',
'inventor-surname#',
'inventor#-surname',
'invent#',
'invent-#',
}
local alias_patterns_date = { -- normal lua patterns for most cs1|2-like templates
'|%s*year%s*=%s*',
'|%s*date%s*=%s*',
'|%s*publication%-?date%s*=%s*',
'|%s*air%-?date%s*=%s*',
}
local alias_patterns_harvc_date = { -- normal lua patterns for harvc template
'|%s*anchor%-year%s*=%s*',
'|%s*year%s*=%s*',
}
local alias_patterns_patent_date = { -- normal lua patterns for cite patent templates
'|%s*issue%-date%s*=%s*',
'|%s*gdate%s*=%s*',
'|%s*publication%-date%s*=%s*',
'|%s*pubdate%s*=%s*',
}
local patterns_date = { -- normal lua patterns
'(%d%d%d%d–%d%d%d%d%l?)$', -- YYYY–YYYY four-digit year range at end (Season YYYY–YYYY); with or without dab
'^(%d%d%d%d–%d%d%l?)$', -- YYYY–YY two-digit year range; with or without dab
'^(c%. %d%d%d%d?%l?)$', -- three- or four-digit circa year; with or without dab
'(%d%d%d%d?%l?)$', -- three- or four-digit year at end of date (dmy or mdy); with or without dab
'^(%d%d%d%d?%l?)', -- three- or four-digit year at beginning of date (ymd or YYYY); with or without dab
'^(n%.d%.%l?)$', -- 'no date' with dots; with or without dab
'^(nd%l?)$', -- 'no date' without dots; with or without dab
}
local patterns_tags = {
'<nowiki>.-</nowiki>',
'<!%-%-.-%-%->',
'<pre>.-</pre>',
'<syntaxhighlight.->.-</syntaxhighlight>',
'<source.->.-</source>', -- deprecated alias of syntaxhighlight tag
}
local template_skip = { -- templates to be skipped for whatever reason; mostly because they resemble cs1-like templates
['Citation-attribution'] = true,
}
local Article_content;
local anchor_id_list = {}; -- exported tables
local template_list = {};
local article_whitelist = {};
--[[--------------------------< A R T I C L E _ C O N T E N T _ G E T >----------------------------------------
get article content, remove certain html-like tags and their content so that this code doesn't include any citation
templates inside the tags as valid tagets; they are not.
]]
local function article_content_get ()
if not Article_content then
Article_content = mw.title.getCurrentTitle():getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
for _, tag in ipairs (patterns_tags) do
Article_content = Article_content:gsub (tag, ''); -- remove certain html-like tags and their content
end
end
end
--[[--------------------------< S F N R E F _ G E T >----------------------------------------------------------
make an anchor id from the contents of {{sfnref}} or {{harvid}}. this function assumes that {{sfnref}} and {{harvid}}
are correctly formed.
]]
local function sfnref_get (template)
template = template:gsub ('{{%s*(.-)%s*}}', '%1'); -- strip bounding template markup and trim
local parts = mw.text.split (template, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
local anchor_id = {};
if redirects_sfnref[parts[1]:lower()] then
anchor_id[1] = 'CITEREF';
else
return nil; -- not an sfnref or harvid template
end
local i = 2; -- indexer into parts{} table
local j = 2; -- indexer into anchor_id{} table which already has 'CITEREF' at [1]
while parts[i] and 7 > j do -- loop through what should be just positional parameters for names and year (2-6 four names and a date)
if not parts[i]:find ('=') then -- look for equal sign (named paraneter in a template that doesn't support named parameters)
anchor_id[j] = parts[i]; -- positional parameters are saved
j = j+1; -- bump the anchor_id{} indexer
end
i = i+ 1; -- bump the parts{} indexer
end
return table.concat (anchor_id, '');
end
--[[--------------------------< D A T E _ G E T >--------------------------------------------------------------
extract year from one of |year=, |date=, |publicationdate=, or |publication-date in that order. Does not error
check (that is left to the cs1|2 templates to do)
also gets date from |<date alias>={{date|...}}
]]
local function date_get (template, aliases)
local date;
local rvalue;
for _, pattern in ipairs (aliases) do -- spin through the date alias patterns
rvalue = tostring(template):match (pattern); -- is this |<date alias>= used (tostring() because something makes match() think template is a table)
if rvalue then
rvalue = tostring(template):match (pattern .. '(%b{})'); -- is rvalue a template?
if rvalue then
rvalue = rvalue:gsub ('{{%s*(.-)%s*}}', '%1'); -- strip bounding template markup and trim
local parts = mw.text.split (rvalue, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
if redirects_date[parts[1]:lower()] then -- if parts[1] names {{date}} or redirect
rvalue = parts[2]; -- assume that date template is properly formed, first positional parameter is the date
else
return ''; -- |date= holds some other template than {{date}} or redirect
end
else
rvalue = template:match (pattern .. '([^|}]+)');
if rvalue then -- if rvalue is something
rvalue = mw.text.trim (rvalue); -- trim it
end
if not rvalue or '' == rvalue then -- if rvale was nothing or trimed to nothing
rvalue = nil; -- ensure that it is unset so we can try the next parameter in the list
end
end
if rvalue then
for _, pattern in ipairs (patterns_date) do -- spin through the recognized date formats
date = rvalue:match (pattern); -- attempt to extract year portion according to the pattern
if date then
return date; -- matched so return;
end
end
break; -- found a date but it was malformed so abandon
end
end
end
return ''; -- no date param or date param doesn't hold a recognized date; empty string for concatenation
end
--[[--------------------------< V N A M E S _ G E T >----------------------------------------------------------
extract names from |vauthors= or |veditors=; there is no |vcontributors= parameter.
splits the v parameter value at the comma; correctly handles accept-as-witten markup when used to wrap a comma-
separated names (corporate)
]]
local function vnames_get (params, vparam)
local vnames = {}; -- first four author or editor names go here
local split = {}; -- temp table to assist in decoding accept-as-witten-markup
if params[vparam] then -- test for |vauthors= or |veditor=
split = mw.text.split (params[vparam], '%s*,%s*'); -- this will separate portions of ((Black, Brown, White, an Co.))
local i = 1; -- an indexer
while split[i] do
if split[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of comma-separated accept-as-witten; this segment has the opening doubled parens
local name = split[i];
i=i+1; -- bump indexer to next segment
while split[i] do
name = name .. ', ' .. split[i]; -- concatenate with previous segments
if split[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parens
break; -- and done reassembling so
end
i=i+1; -- bump indexer
end
table.insert (vnames, name); -- and add accept-as-witten name to the vnames table
else
table.insert (vnames, split[i]); -- and add name to the vnames table
end
i=i+1; -- bump indexer
if 5 == i then break; end -- limit to four names
end
for i, vname in ipairs (vnames) do
if not vname:match ('%(%(.-%)%)') then -- without accept-this-value-as-written markup
vnames[i] = vname:gsub ('(.-)%s+%u+$', '%1'); -- extract and save surname(s)
end
end
for i, vname in ipairs (vnames) do -- repeat, this time for accept-this-value-as-written markup
vnames[i] = vname:gsub ('%(%((.-)%)%)', '%1'); -- remove markup if present and save the whole name
end
end
return 0 ~= #vnames and table.concat (vnames) or nil -- return a concatenation of the vnames; nil else
end
--[[--------------------------< N A M E S _ G E T >------------------------------------------------------------
cs1|2 makes anchor id from contributor, author, or editor name-lists in that order
get the names from the cs1|2 template; if there are no contributor names, try author names, then try editor names.
returns concatenated names in enumeration order when successful; nil else
empty name (nameholding parameter n is present without value) and missing name (nameholding parameter n is not
present) are included as empty string with all other names
]]
local function names_get (params, aliases_list)
local names = {}; -- first four author or editor names go here
local enum_alias; -- alias with '#' replaced with a digit
for enum=1, 4 do -- four names only
for i, alias in ipairs (aliases_list) do
if not names[enum] then -- hanven't found a previous alias with this [enum]? see if we can find this alias with this enum
enum_alias = alias:gsub ('#', enum); -- replace '#' to make 'lastn'
if 1 == enum then -- because |last= and last1= are exact aliases
if params[enum_alias] then -- test |last1= first
names[enum] = params[enum_alias]; -- found so save the value assigned to |last1=
break; -- next enum
else
enum_alias = alias:gsub ('#', ''); -- replace '#' to make 'last'
if params[enum_alias] then
names[enum] = params[enum_alias]; -- found so save the value assigned to |last=
break; -- next enum
end
end
else -- here for enum 2, 3, 4
if params[enum_alias] then
names[enum] = params[enum_alias]; -- found so save the value assigned to |lastn=
break; -- next enum
end
end
end
end
end
for enum=1, 4 do -- spin through the names table and
local name = names[enum];
if not name then -- when nameholding parameter n is not present (nil)
name = ''; -- convert to empty string for concatenation
end
name = name:gsub('%(%((.-)%)%)', '%1'); -- remove accept-as-written markup if present
names[enum] = name; -- save the modified name
end
local name_str = table.concat (names); -- concatenate the names
return '' ~= name_str and name_str or nil; -- return the concatenation if not empty string; nil else
end
--[[--------------------------< T E M P L A T E _ S T R I P >--------------------------------------------------
removes the citation or havrc template's {{ and }} markup then removes, in whole, any templates found inside the
citation or harvc template.
Templates are not allowed in parameters that are made part of COinS metadata; yet, they will appear. cs1|2 does
not see the template markup but instead sees the result of the template as html. cs1|2 strips the html which
leaves the displayed value for the anchor id. We can't do that here so, because templates aren't allowed in
parameters, we simply discard any templates found in the cs1|2 template.
this may leave a |lastn= parameter empty which will be treated as if it were really empty as cs1|2 do (three authors,
|last2= empty -> CITEREFLast1Last3YYYY (the harv and sfn render: 'Last1, & Last3 YYYY' with CITEREFLast1Last3YYYY).
]]
local function template_strip (template)
template = template:gsub ('^{{%s*', ''):gsub ('%s*}}$', '', 1); -- remove outer {{ and }} (cs1|2 template delimiters with trailing/leading whitespace)
template = template:gsub ('%b{}', ''); -- remove any templates from the cs1|2 template
return template;
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other lua magic pattern characters
return argument;
end
--[=[-------------------------< W I K I L I N K _ S T R I P >--------------------------------------------------
Wikilink markup does not belong in an anchor id and can / does confuse the code that parses apart citation and
harvc templates so here we remove any wiki markup:
[[link|label]] -> label
[[link]] -> link
]=]
local function wikilink_strip (template)
for wikilink in template:gmatch ('%[%b[]%]') do -- get a wikilink
template = template:gsub ('%[%b[]%]', '__57r1P__', 1); -- install a marker
if wikilink:match ('%[%[.-|(.-)%]%]') then
wikilink = wikilink:match ('%[%[.-|(.-)%]%]'); -- extract label from complex [[link|label]] wikilink
else
wikilink = wikilink:match ('%[%[(.-)%]%]'); -- extract link from simple [[link]] wikilinks
end
wikilink = escape_lua_magic_chars (wikilink); -- in case there are lua magic characters in wikilink
template = template:gsub ('__57r1P__', wikilink, 1); -- replace the marker with the appropriate text
end
return template;
end
--[[--------------------------< T E M P L A T E _ N A M E _ G E T >--------------------------------------------
return the citation or harvc template's name; convert to lower case and trim leading and trailing whitespace;
when the template is a sandbox the subpage portion of the template name is omitted from the returned template name
{{Cite book/new |...}} returns cite book
]]
local function template_name_get (template)
local template_name = template:match ('^{{%s*([^/|}]+)'); -- get template name; ignore subpages ~/new, ~/sandbox; parser functions
if not template_name or template_name:match ('^#') then -- parser functions, magic words don't count as templates
return nil; -- could not get template name from (possibly corrupt) template; extraneous opening { mid template can cause this;
end;
template_name = template_name:gsub ('%s*$', ''); -- trim trailing whitespace; leading whitespace already removed
return Lang_obj:ucfirst (template_name); -- first character in template name must be uppercase (same as canonical template name) TODO: better way to do this?
end
--[[--------------------------< T E M P L A T E _ P A R A M S _ G E T >----------------------------------------
parse apart a template's parameters and store in the params table where key is the parameter's name and value is
the parameter's value; empty parameters are not saved
]]
local function template_params_get (template, params_t)
template = wikilink_strip (template); -- because piped wikilinks confuse code that builds params_t{} and because wikilinks not allowed in an anchor id
-- strip templates after getting |ref= value because |ref={{sfnref}} and |ref={{harvid}} are allowed
template = template_strip (template); -- because template markup can confuse code that builds params_t{} and because templates in name parameters are not allowed
local temp_t = mw.text.split (template, '%s*|%s*'); --split on the pipe
for _, param in ipairs (temp_t) do
if param:find ('=', 1, true) then -- a named parameter?
local k, v = param:match ('%s*([^=]-)%s*=%s*([^|}]+)');
if v then -- there must be a value
if '' ~= v and not v:match ('^%s$') then -- skip when value is empty string or only whitespace
params_t[k] = mw.text.trim (v); -- add trimmed value else
end
end
end
end
end
--[[--------------------------< C I T E R E F _ M A K E _ H A R V C >------------------------------------------
makes anchor_id from {{harvc}} or redirects
]]
local function anchor_id_make_harvc (template)
local date = date_get (template, alias_patterns_harvc_date); -- get date; done here because might be in {{date}}; return date if valid; empty string else
local anchor_id;
local params = {}; -- table of harvc parameters
local id; -- custom anchor id for this {{harvc}} template
id = template:match ('|%s*id%s*=%s*(%b{})'); -- in case |id={{sfnref}}; done here because templates will be stripped
template_params_get (template, params); -- build a table of template parameters and their values; this strips wikilinks and templates
if id then -- when set is {{sfnref}} or {{harvid}} template
return sfnref_get (id); -- returns content of {{sfnref}} or {{harvid}}; nil else
end
if params.id then -- custom anchor for this {{harvc}} template (text)
return params.id; -- |id= value as written
end
anchor_id = names_get (params, aliases_harvc_author); -- get the harvc contributor names
if anchor_id then -- if names were gotten
return 'CITEREF' .. anchor_id .. date;
end
return nil; -- no names; no anchor_id
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ W R A P P E R >----------------------------------
for wrapper templates
inspect externally visible |ref= to decide what to do:
|ref= - empty or missing: get names and date from whitelist defaults; override defaults from externally visible template parameters
|ref=harv - same as empty or missing
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
|ref={{Harvid|name|name|name|name|year}} - assemble an anchor id from {{harvid}} positional parameters
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
]]
local function anchor_id_make_wrapper (template)
local ref; -- content of |ref=
local template_name; -- name of the template
local anchor_id; -- the assembled anchor id from this template
local date;
local name_default;
local date_default;
local vol;
local params = {}; -- table of template parameters
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
end
date = date_get (template, alias_patterns_date); -- get date; done here because might be in {{date}}
-- if '' == date then
-- date = whitelist.wrapper_templates[template_name][2] or ''; -- no externally visible date so get default date
-- end
ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the wrapper template
if not ref then
if template:match ('|%s*ref%s*=([^|}]+)') then -- |ref={{template}} not found; if there is a |ref= param with an assigned value
ref = template:match ('|%s*ref%s*=([^|}]+)'); -- get the value; whitespace is a 'value'
if ref then -- nil when |ref=|... or when |ref=}} (no spaces between assignment operator and pipe or closing brace)
ref = mw.text.trim (ref); -- something, could be just whitespace, so trim leading / trailing whitespace
if '' == ref then -- trimming a string of whitespace makes an empty string
ref = nil; -- make empty ref same as missing ref
end
end
end
end
template_params_get (template, params); -- build a table of template parameters and their values
if whitelist.wrapper_templates[template_name][1] then -- is this wrapper a simple-default wrapper?
name_default = whitelist.wrapper_templates[template_name][1]; -- get the default names
date_default = whitelist.wrapper_templates[template_name][2]; -- get the default date
else
vol = params['volume'] or 'default';
if not whitelist.wrapper_templates[template_name][vol] then -- make sure this volume exists
vol = 'default'; -- doesn't exist, use default volume
end
name_default = whitelist.wrapper_templates[template_name][vol][1]; -- get the default names
date_default = whitelist.wrapper_templates[template_name][vol][2]; -- get the default date
end
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty
anchor_id = names_get (params, aliases_contributor) or -- get contributor, author, or editor names
names_get (params, aliases_author) or
vnames_get (params, 'vauthors') or -- |vauthors=
names_get (params, aliases_editor) or
vnames_get (params, 'veditors') or -- |veditors=
name_default; -- default names from whitelist
-- whitelist.wrapper_templates[template_name][1]; -- default names from whitelist
if '' == date then -- if date not provided in the template
date = date_default; -- use the default date from whitelist
end
if anchor_id then -- if names were gotten
anchor_id = 'CITEREF' .. anchor_id .. date;
end
elseif ref:match ('%b{}') then -- ref holds a template
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
elseif 'none' == ref then -- |ref=none
return nil; -- anchor id expicitly suppressed
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
end
return anchor_id; -- anchor_id text; nil else
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ C S 1 2 >----------------------------------------
for cs1|2 template and cs1-like templates
inspect |ref= to decide what to do:
|ref= - empty or missing: get names and date from template parameters; all cs1|2 create CITEREF anchor IDs
|ref=harv - get names and date from template parameters
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
|ref={{Harvid|name|name|name|name|year}} - assemble an anchor id from {{harvid}} positional parameters
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
]]
local function anchor_id_make_cs12 (template)
local ref; -- content of |ref=
local template_name; -- name of the template
local anchor_id; -- the assembled anchor id from this template
local date;
local params = {}; -- table of template parameters
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
end
if redirects_patent[template_name] then
date = date_get (template, alias_patterns_patent_date); -- get date; done here because might be in {{date}}
else
date = date_get (template, alias_patterns_date);
end
ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the cs1|2 template
if not ref then
if template:match ('|%s*ref%s*=([^|}]+)') then -- |ref={{template}} not found; if there is a |ref= param with an assigned value
ref = template:match ('|%s*ref%s*=([^|}]+)'); -- get the value; whitespace is a 'value'
if ref then -- nil when |ref=|... or when |ref=}} (no spaces between assignment operator and pipe or closing brace)
ref = mw.text.trim (ref); -- something, could be just whitespace, so trim leading / trailing whitespace
if '' == ref then -- trimming a string of whitespace makes an empty string
ref = nil; -- make empty ref same as missing ref
end
end
end
end
template_params_get (template, params); -- build a table of template parameters and their values
if not ref then -- |ref= not set, might be cite LSA which doesn't support |ref=
if 'cite lsa' == template_name then
return 'CITEREF' .. (params.last or '') .. (params.year or ''); -- cite LSA always creates an anchor id using only |last= and |year= (no aliases)
end
end
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty
if redirects_patent[template_name] then -- if this is a cite patent template
anchor_id = names_get (params, aliases_inventor); -- inventor names only
else -- cs1|2 template
anchor_id = names_get (params, aliases_contributor) or -- get contributor, author, or editor names
names_get (params, aliases_author) or
vnames_get (params, 'vauthors') or -- |vauthors=
names_get (params, aliases_editor) or
vnames_get (params, 'veditors'); -- |veditors=
end
if anchor_id then -- if names were gotten
anchor_id = 'CITEREF' .. anchor_id .. date;
end
elseif ref:match ('%b{}') then -- ref holds a template
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
elseif 'none' == ref and not redirects_patent[template_name] then -- |ref=none; not supported by cite patent
return nil; -- anchor id expicitly suppressed
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
end
return anchor_id; -- anchor_id text; nil else
end
--[[--------------------------< L I S T _ A D D >--------------------------------------------------------------
adds an <item> to <list> table; for anchor IDs, the boolean <encode> argument must be set true; no return value
]]
local function list_add (item, list, encode)
if item then -- if there was an item
if encode then -- for anchor IDs ...
item = mw.uri.anchorEncode (item); -- encode to remove wikimarkup, convert spaces to underscores etc
end
if not list[item] then -- if not already saved
list[item] = 1; -- save it
else -- here when this item already saved
list[item] = list[item] + 1; -- to indicate that there are multiple items
end
end
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ A N C H O R >------------------------------------
make anchor IDs from {{anchor}}; there may be more than one because {{anchor}} is not limited to the number of
anchors it may hold.
]]
local function anchor_id_make_anchor (template, anchor_id_list)
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = wikilink_strip (template); -- strip any wikilink markup (there shouldn't be any but just in case)
local params = {};
local anchor_id;
for param in template:gmatch ('%b{}') do -- loop through the template; remove and save templates (presumed to be sfnref or harvid)
table.insert (params, param); -- save it
template = template:gsub ('%b{}', '', 1); -- remove it from source template
end
for _, t in ipairs (params) do -- spin through the templates in params
anchor_id = sfnref_get (t); -- attempt to decode {{sfnref}} and {{harvid}}
if anchor_id then -- nil when not {{sfnref}} or {{harvid}}
list_add (anchor_id, anchor_id_list, true); -- add anchor ID to the list
end
end
template = template:gsub ('|%s*|', '|'); -- when pipe follows pipe with or without white space, remove extraneous pipe
template = template:gsub ('^|', ''):gsub('|$', ''); -- remove extraneous leading and trailing pipes
params = mw.text.split (template, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
for _, t in ipairs (params) do -- spin through the anchor IDs
anchor_id = mw.text.trim (t); -- trim white space
if '' ~= anchor_id then -- should always have something
list_add (anchor_id, anchor_id_list, true); -- add anchor ID to the list
end
end
end
--[[--------------------------< T E M P L A T E _ L I S T _ A D D >--------------------------------------------
makes a list of templates use in the article.
]]
local function template_list_add (template)
local template = template:match ('{{%s*(.-)[|}]'); -- keep the case of the template - this is different from template_name_get()
if template and not template:match ('^#') then -- found a template or magic word; ignore magic words
template=mw.text.trim (template); -- trim whitespace
template = Lang_obj:ucfirst (template); -- first character in template name must be uppercase (same as canonical template name) TODO: better way to do this?
list_add (template, template_list); -- add to list with (unused) tally
end
end
--[[--------------------------< A N C H O R _ I D _ L I S T _ M A K E >----------------------------------------
makes a list of anchor ids from cs1|2, cs1|2-like, vcite xxx, harvc, anchor, wikicite templates
Because cs1|2 wrapper templates can, and often do, hide the author and date parameters inside the wrapper,
these parameters are not available in the article's wikisource so {{harv}}, {{sfn}}, and {{harvc}} templates that
link correctly to those wrapper templates will incorrectly show error messages. Use |ignore-err=yes in the {{harv}},
{{sfn}}, and {{harvc}} templates to supress the error message.
creates a list of templates used in the article for use with the whitelist
creates a list of article-local whitelisted anchor IDs from {{sfn whitelist}}
]]
local function anchor_id_list_make ()
article_content_get (); -- attempt to get this article's content
if '' == Article_content then -- when there is no article content
return ''; -- no point in continuing
end
local template; -- place to hold the template that we found
local template_name;
local anchor_id; -- place to hold an anchor id as it is extracted / decoded
local find_pattern = '%f[{]{{[^{]';
local tstart, tend = Article_content:find (find_pattern); -- find the first template; do not find template variables: {{{template var|}}}
while tstart do
template = Article_content:match ('%b{}', tstart); -- get the whole template
if not template then
break; -- template is nil for some reason (last template missing closing }} for example) so declare ourselves done
end
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
template_list_add (template); -- add this template's name to the list
if data.known_templates_cs12 [template_name] then
anchor_id = anchor_id_make_cs12 (template); -- extract an anchor id from this template
list_add (anchor_id, anchor_id_list, true)
elseif data.known_templates_vcite [template_name] then
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the vcite template
if ref then -- |ref={{template}}
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
list_add (anchor_id, anchor_id_list, true);
else
local params = {};
template_params_get (template, params); -- build a table of template parameters and their values
anchor_id = params['ref']; -- when both set, vcite uses value from |ref=
if not anchor_id and params['harvid'] then
anchor_id = 'CITEREF' .. params['harvid']; -- in vcite, |harvid= auto-adds 'CITEREF' prefix to the value in |harvid=
end
list_add (anchor_id, anchor_id_list, true);
end
elseif data.known_templates_harvc [template_name] then
anchor_id = anchor_id_make_harvc (template); -- extract an anchor id from this template
list_add (anchor_id, anchor_id_list, true);
elseif data.known_templates_wikicite [template_name] then
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}}
if ref then
anchor_id = sfnref_get (ref);
elseif template:match ('|%s*ref%s*=([^|}]+)') then
anchor_id = template:match ('|%s*ref%s*=([^|}]+)'); -- plain-text
elseif template:match ('|%s*id%s*=%s*(%b{})') then
ref = template:match ('|%s*id%s*=%s*(%b{})');
anchor_id = 'Reference-' .. sfnref_get (ref);
elseif template:match ('|%s*id%s*=([^|}]+)') then
anchor_id = 'Reference-' .. template:match ('|%s*id%s*=([^|}]+)'); -- plain-text
else
anchor_id = nil; -- no matches, ensure that anchor_id has no value
end
if anchor_id then
list_add (anchor_id, anchor_id_list, true);
end
elseif data.known_templates_anchor [template_name] then
anchor_id_make_anchor (template, anchor_id_list); -- extract anchor ids from this template if any
elseif data.known_templates_sfn_whitelist [template_name] then
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = mw.text.trim (template, '%s|'); -- trim leading trailing white space and pipes
template = mw.text.split (template, '%s*|%s*'); -- make a table of the template's parameters
for _, anchor_id in ipairs (template) do -- spin through this template's parameter
if '' ~= anchor_id and not article_whitelist[anchor_id] then
anchor_id = mw.uri.anchorEncode (anchor_id)
article_whitelist[anchor_id] = 1; -- add to the whitelist
end
end
elseif template_name and whitelist.wrapper_templates[template_name] then
anchor_id = anchor_id_make_wrapper (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
elseif template_name and template_name:match ('^Cit[ea]') then -- not known, not known wrapper; last gasp, try as cs1-like
anchor_id = anchor_id_make_cs12 (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
end
tstart, tend = Article_content:find (find_pattern, tend); -- search for another template; begin at end of last search
end
mw.logObject (anchor_id_list, 'anchor_id_list');
mw.logObject (template_list, 'template_list');
mw.logObject (article_whitelist, 'article_whitelist');
return anchor_id_list;
end
--[[--------------------------< E X P O R T E D _ T A B L E S >------------------------------------------------
]]
return {
anchor_id_list = anchor_id_list_make(), -- table of anchor ids available in this article
article_whitelist = article_whitelist, -- table of anchor ids with false-positive error message to be suppressed
template_list = template_list, -- table of templates used in this article
}
9cf1091b65b65bfb32bb0aa2b73bb581d19e99f1
Module:Navbox/styles.css
828
115
245
2021-12-21T22:10:10Z
Canopus >Izno
0
remove qualifications on th - this will remove styling from "hand-crafted" navboxes, but there's no other elegant way to deal with it. see talk page
text
text/plain
/* {{pp|small=y}} */
.navbox {
box-sizing: border-box;
border: 1px solid #a2a9b1;
width: 100%;
clear: both;
font-size: 88%;
text-align: center;
padding: 1px;
margin: 1em auto 0; /* Prevent preceding content from clinging to navboxes */
}
.navbox .navbox {
margin-top: 0; /* No top margin for nested navboxes */
}
.navbox + .navbox, /* TODO: remove first line after transclusions have updated */
.navbox + .navbox-styles + .navbox {
margin-top: -1px; /* Single pixel border between adjacent navboxes */
}
.navbox-inner,
.navbox-subgroup {
width: 100%;
}
.navbox-group,
.navbox-title,
.navbox-abovebelow {
padding: 0.25em 1em;
line-height: 1.5em;
text-align: center;
}
.navbox-group {
white-space: nowrap;
/* @noflip */
text-align: right;
}
.navbox,
.navbox-subgroup {
background-color: #fdfdfd;
}
.navbox-list {
line-height: 1.5em;
border-color: #fdfdfd; /* Must match background color */
}
.navbox-list-with-group {
text-align: left;
border-left-width: 2px;
border-left-style: solid;
}
/* cell spacing for navbox cells */
/* Borders above 2nd, 3rd, etc. rows */
/* TODO: figure out how to replace tr as structure;
* with div structure it should be just a matter of first-child */
tr + tr > .navbox-abovebelow,
tr + tr > .navbox-group,
tr + tr > .navbox-image,
tr + tr > .navbox-list {
border-top: 2px solid #fdfdfd; /* Must match background color */
}
.navbox-title {
background-color: #ccf; /* Level 1 color */
}
.navbox-abovebelow,
.navbox-group,
.navbox-subgroup .navbox-title {
background-color: #ddf; /* Level 2 color */
}
.navbox-subgroup .navbox-group,
.navbox-subgroup .navbox-abovebelow {
background-color: #e6e6ff; /* Level 3 color */
}
.navbox-even {
background-color: #f7f7f7;
}
.navbox-odd {
background-color: transparent;
}
/* TODO: figure out how to remove reliance on td as structure */
.navbox .hlist td dl,
.navbox .hlist td ol,
.navbox .hlist td ul,
.navbox td.hlist dl,
.navbox td.hlist ol,
.navbox td.hlist ul {
padding: 0.125em 0;
}
.navbox .navbar {
display: block;
font-size: 100%;
}
.navbox-title .navbar {
/* @noflip */
float: left;
/* @noflip */
text-align: left;
/* @noflip */
margin-right: 0.5em;
}
e80b0d7a5770e6e105dab832deb6c37a5245ebc6
Template:Other uses
10
99
213
2021-12-26T18:42:03Z
Canopus >Nihiltres
0
Removed categorization system as redundant
wikitext
text/x-wiki
{{#invoke:other uses|otheruses}}<noinclude>{{documentation}}</noinclude>
3bd6c67c92b11a14d2e58145b096152fbc066580
Module:Hatnote list
828
109
233
2021-12-26T20:05:24Z
Canopus >Nihiltres
0
Undid revision 1062166786 by [[Special:Contributions/Matthiaspaul|Matthiaspaul]] ([[User talk:Matthiaspaul|talk]]); should be fixed now, and if not, please ping me with examples as I couldn't reproduce the original error
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Hatnote list --
-- --
-- This module produces and formats lists for use in hatnotes. In particular, --
-- it implements the for-see list, i.e. lists of "For X, see Y" statements, --
-- as used in {{about}}, {{redirect}}, and their variants. Also introduced --
-- are andList & orList helpers for formatting lists with those conjunctions. --
--------------------------------------------------------------------------------
local mArguments --initialize lazily
local mFormatLink = require('Module:Format link')
local mHatnote = require('Module:Hatnote')
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local p = {}
--------------------------------------------------------------------------------
-- List stringification helper functions
--
-- These functions are used for stringifying lists, usually page lists inside
-- the "Y" portion of "For X, see Y" for-see items.
--------------------------------------------------------------------------------
--default options table used across the list stringification functions
local stringifyListDefaultOptions = {
conjunction = "and",
separator = ",",
altSeparator = ";",
space = " ",
formatted = false
}
--Searches display text only
local function searchDisp(haystack, needle)
return string.find(
string.sub(haystack, (string.find(haystack, '|') or 0) + 1), needle
)
end
-- Stringifies a list generically; probably shouldn't be used directly
local function stringifyList(list, options)
-- Type-checks, defaults, and a shortcut
checkType("stringifyList", 1, list, "table")
if #list == 0 then return nil end
checkType("stringifyList", 2, options, "table", true)
options = options or {}
for k, v in pairs(stringifyListDefaultOptions) do
if options[k] == nil then options[k] = v end
end
local s = options.space
-- Format the list if requested
if options.formatted then
list = mFormatLink.formatPages(
{categorizeMissing = mHatnote.missingTargetCat}, list
)
end
-- Set the separator; if any item contains it, use the alternate separator
local separator = options.separator
for k, v in pairs(list) do
if searchDisp(v, separator) then
separator = options.altSeparator
break
end
end
-- Set the conjunction, apply Oxford comma, and force a comma if #1 has "§"
local conjunction = s .. options.conjunction .. s
if #list == 2 and searchDisp(list[1], "§") or #list > 2 then
conjunction = separator .. conjunction
end
-- Return the formatted string
return mw.text.listToText(list, separator .. s, conjunction)
end
--DRY function
function p.conjList (conj, list, fmt)
return stringifyList(list, {conjunction = conj, formatted = fmt})
end
-- Stringifies lists with "and" or "or"
function p.andList (...) return p.conjList("and", ...) end
function p.orList (...) return p.conjList("or", ...) end
--------------------------------------------------------------------------------
-- For see
--
-- Makes a "For X, see [[Y]]." list from raw parameters. Intended for the
-- {{about}} and {{redirect}} templates and their variants.
--------------------------------------------------------------------------------
--default options table used across the forSee family of functions
local forSeeDefaultOptions = {
andKeyword = 'and',
title = mw.title.getCurrentTitle().text,
otherText = 'other uses',
forSeeForm = 'For %s, see %s.',
}
--Collapses duplicate punctuation
local function punctuationCollapse (text)
local replacements = {
["%.%.$"] = ".",
["%?%.$"] = "?",
["%!%.$"] = "!",
["%.%]%]%.$"] = ".]]",
["%?%]%]%.$"] = "?]]",
["%!%]%]%.$"] = "!]]"
}
for k, v in pairs(replacements) do text = string.gsub(text, k, v) end
return text
end
-- Structures arguments into a table for stringification, & options
function p.forSeeArgsToTable (args, from, options)
-- Type-checks and defaults
checkType("forSeeArgsToTable", 1, args, 'table')
checkType("forSeeArgsToTable", 2, from, 'number', true)
from = from or 1
checkType("forSeeArgsToTable", 3, options, 'table', true)
options = options or {}
for k, v in pairs(forSeeDefaultOptions) do
if options[k] == nil then options[k] = v end
end
-- maxArg's gotten manually because getArgs() and table.maxn aren't friends
local maxArg = 0
for k, v in pairs(args) do
if type(k) == 'number' and k > maxArg then maxArg = k end
end
-- Structure the data out from the parameter list:
-- * forTable is the wrapper table, with forRow rows
-- * Rows are tables of a "use" string & a "pages" table of pagename strings
-- * Blanks are left empty for defaulting elsewhere, but can terminate list
local forTable = {}
local i = from
local terminated = false
-- If there is extra text, and no arguments are given, give nil value
-- to not produce default of "For other uses, see foo (disambiguation)"
if options.extratext and i > maxArg then return nil end
-- Loop to generate rows
repeat
-- New empty row
local forRow = {}
-- On blank use, assume list's ended & break at end of this loop
forRow.use = args[i]
if not args[i] then terminated = true end
-- New empty list of pages
forRow.pages = {}
-- Insert first pages item if present
table.insert(forRow.pages, args[i + 1])
-- If the param after next is "and", do inner loop to collect params
-- until the "and"'s stop. Blanks are ignored: "1|and||and|3" → {1, 3}
while args[i + 2] == options.andKeyword do
if args[i + 3] then
table.insert(forRow.pages, args[i + 3])
end
-- Increment to next "and"
i = i + 2
end
-- Increment to next use
i = i + 2
-- Append the row
table.insert(forTable, forRow)
until terminated or i > maxArg
return forTable
end
-- Stringifies a table as formatted by forSeeArgsToTable
function p.forSeeTableToString (forSeeTable, options)
-- Type-checks and defaults
checkType("forSeeTableToString", 1, forSeeTable, "table", true)
checkType("forSeeTableToString", 2, options, "table", true)
options = options or {}
for k, v in pairs(forSeeDefaultOptions) do
if options[k] == nil then options[k] = v end
end
-- Stringify each for-see item into a list
local strList = {}
if forSeeTable then
for k, v in pairs(forSeeTable) do
local useStr = v.use or options.otherText
local pagesStr =
p.andList(v.pages, true) or
mFormatLink._formatLink{
categorizeMissing = mHatnote.missingTargetCat,
link = mHatnote.disambiguate(options.title)
}
local forSeeStr = string.format(options.forSeeForm, useStr, pagesStr)
forSeeStr = punctuationCollapse(forSeeStr)
table.insert(strList, forSeeStr)
end
end
if options.extratext then table.insert(strList, punctuationCollapse(options.extratext..'.')) end
-- Return the concatenated list
return table.concat(strList, ' ')
end
-- Produces a "For X, see [[Y]]" string from arguments. Expects index gaps
-- but not blank/whitespace values. Ignores named args and args < "from".
function p._forSee (args, from, options)
local forSeeTable = p.forSeeArgsToTable(args, from, options)
return p.forSeeTableToString(forSeeTable, options)
end
-- As _forSee, but uses the frame.
function p.forSee (frame, from, options)
mArguments = require('Module:Arguments')
return p._forSee(mArguments.getArgs(frame), from, options)
end
return p
d0828422b1aa0d0d0092d699d059c9e882260398
Template:Order of magnitude
10
137
289
2022-01-02T09:08:29Z
Canopus >Dinoguy1000
0
fix "|=foo" bug
wikitext
text/x-wiki
<includeonly>{{safesubst:<noinclude/>#ifexpr:{{{1|0}}}=0
|{{safesubst:<noinclude/>#ifexpr:abs{{{1|0}}}1=1
|0
|{{safesubst:<noinclude/>#expr:floor((ln(abs{{{1}}}1)/ln10)+1)}}
}}
|{{safesubst:<noinclude/>#expr:floor((ln(abs({{{1|0}}}) )/ln 10)+1E((abs{{{1|0}}}>1E100 or abs{{{1|0}}}<1E-100)-14))}}
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
cede5694e8ebb404ecdd17ae1f8e1c5d19562728
Module:Navbar/styles.css
828
112
239
2022-01-03T23:12:15Z
Canopus >Izno
0
navbar styles that were moved to parent templates
text
text/plain
/* {{pp|small=yes}} */
.navbar {
display: inline;
font-size: 88%;
font-weight: normal;
}
.navbar-collapse {
float: left;
text-align: left;
}
.navbar-boxtext {
word-spacing: 0;
}
.navbar ul {
display: inline-block;
white-space: nowrap;
line-height: inherit;
}
.navbar-brackets::before {
margin-right: -0.125em;
content: '[ ';
}
.navbar-brackets::after {
margin-left: -0.125em;
content: ' ]';
}
.navbar li {
word-spacing: -0.125em;
}
.navbar a > span,
.navbar a > abbr {
text-decoration: inherit;
}
.navbar-mini abbr {
font-variant: small-caps;
border-bottom: none;
text-decoration: none;
cursor: inherit;
}
.navbar-ct-full {
font-size: 114%;
margin: 0 7em;
}
.navbar-ct-mini {
font-size: 114%;
margin: 0 4em;
}
9d4056f949b4f0b159e3d40dfb1a5f01e72f9571
Module:Navbox
828
113
241
2022-01-07T21:39:23Z
Canopus >Izno
0
remove titlegroup per templatestyles section on talk page
Scribunto
text/plain
local p = {}
local navbar = require('Module:Navbar')._navbar
local cfg = mw.loadData('Module:Navbox/configuration')
local getArgs -- lazily initialized
local args
local format = string.format
local function striped(wikitext, border)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = cfg.category.orphan
if border == cfg.keyword.border_subgroup and args[cfg.arg.orphan] ~= cfg.keyword.orphan_yes then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = cfg.class.navbox_odd_part, cfg.class.navbox_even_part
if args[cfg.arg.evenodd] then
if args[cfg.arg.evenodd] == cfg.keyword.evenodd_swap then
first, second = second, first
else
first = args[cfg.arg.evenodd]
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(cfg.marker.regex, changer)) -- () omits gsub count
end
local function processItem(item, nowrapitems)
if item:sub(1, 2) == '{|' then
-- Applying nowrap to lines in a table does not make sense.
-- Add newlines to compensate for trim of x in |parm=x in a template.
return '\n' .. item ..'\n'
end
if nowrapitems == cfg.keyword.nowrapitems_yes then
local lines = {}
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
if prefix and not content:match(cfg.pattern.nowrap) then
line = format(cfg.nowrap_item, prefix, content)
end
table.insert(lines, line)
end
item = table.concat(lines, '\n')
end
if item:match('^[*:;#]') then
return '\n' .. item ..'\n'
end
return item
end
-- we will want this later when we want to add tstyles for hlist/plainlist
local function has_navbar()
return args[cfg.arg.navbar] ~= cfg.keyword.navbar_off
and args[cfg.arg.navbar] ~= cfg.keyword.navbar_plain
and (
args[cfg.arg.name]
or mw.getCurrentFrame():getParent():getTitle():gsub(cfg.pattern.sandbox, '')
~= cfg.pattern.navbox
)
end
local function renderNavBar(titleCell)
if has_navbar() then
titleCell:wikitext(navbar{
[cfg.navbar.name] = args[cfg.arg.name],
[cfg.navbar.mini] = 1,
[cfg.navbar.fontstyle] = (args[cfg.arg.basestyle] or '') .. ';' ..
(args[cfg.arg.titlestyle] or '') ..
';background:none transparent;border:none;box-shadow:none;padding:0;'
})
end
end
local function renderTitleRow(tbl)
if not args[cfg.arg.title] then return end
local titleRow = tbl:tag('tr')
local titleCell = titleRow:tag('th'):attr('scope', 'col')
local titleColspan = 2
if args[cfg.arg.imageleft] then titleColspan = titleColspan + 1 end
if args[cfg.arg.image] then titleColspan = titleColspan + 1 end
titleCell
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.titlestyle])
:addClass(cfg.class.navbox_title)
:attr('colspan', titleColspan)
renderNavBar(titleCell)
titleCell
:tag('div')
-- id for aria-labelledby attribute
:attr('id', mw.uri.anchorEncode(args[cfg.arg.title]))
:addClass(args[cfg.arg.titleclass])
:css('font-size', '114%')
:css('margin', '0 4em')
:wikitext(processItem(args[cfg.arg.title]))
end
local function getAboveBelowColspan()
local ret = 2
if args[cfg.arg.imageleft] then ret = ret + 1 end
if args[cfg.arg.image] then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl)
if not args[cfg.arg.above] then return end
tbl:tag('tr')
:tag('td')
:addClass(cfg.class.navbox_abovebelow)
:addClass(args[cfg.arg.aboveclass])
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.abovestyle])
:attr('colspan', getAboveBelowColspan())
:tag('div')
-- id for aria-labelledby attribute, if no title
:attr('id', args[cfg.arg.title] and nil or mw.uri.anchorEncode(args[cfg.arg.above]))
:wikitext(processItem(args[cfg.arg.above], args[cfg.arg.nowrapitems]))
end
local function renderBelowRow(tbl)
if not args[cfg.arg.below] then return end
tbl:tag('tr')
:tag('td')
:addClass(cfg.class.navbox_abovebelow)
:addClass(args[cfg.arg.belowclass])
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.belowstyle])
:attr('colspan', getAboveBelowColspan())
:tag('div')
:wikitext(processItem(args[cfg.arg.below], args[cfg.arg.nowrapitems]))
end
local function renderListRow(tbl, index, listnum, listnums_size)
local row = tbl:tag('tr')
if index == 1 and args[cfg.arg.imageleft] then
row
:tag('td')
:addClass(cfg.class.noviewer)
:addClass(cfg.class.navbox_image)
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '0 2px 0 0')
:cssText(args[cfg.arg.imageleftstyle])
:attr('rowspan', listnums_size)
:tag('div')
:wikitext(processItem(args[cfg.arg.imageleft]))
end
local group_and_num = format(cfg.arg.group_and_num, listnum)
local groupstyle_and_num = format(cfg.arg.groupstyle_and_num, listnum)
if args[group_and_num] then
local groupCell = row:tag('th')
-- id for aria-labelledby attribute, if lone group with no title or above
if listnum == 1 and not (args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group2]) then
groupCell
:attr('id', mw.uri.anchorEncode(args[cfg.arg.group1]))
end
groupCell
:attr('scope', 'row')
:addClass(cfg.class.navbox_group)
:addClass(args[cfg.arg.groupclass])
:cssText(args[cfg.arg.basestyle])
-- If groupwidth not specified, minimize width
:css('width', args[cfg.arg.groupwidth] or '1%')
groupCell
:cssText(args[cfg.arg.groupstyle])
:cssText(args[groupstyle_and_num])
:wikitext(args[group_and_num])
end
local listCell = row:tag('td')
if args[group_and_num] then
listCell
:addClass(cfg.class.navbox_list_with_group)
else
listCell:attr('colspan', 2)
end
if not args[cfg.arg.groupwidth] then
listCell:css('width', '100%')
end
local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing
if index % 2 == 1 then
rowstyle = args[cfg.arg.oddstyle]
else
rowstyle = args[cfg.arg.evenstyle]
end
local list_and_num = format(cfg.arg.list_and_num, listnum)
local listText = args[list_and_num]
local oddEven = cfg.marker.oddeven
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find(cfg.pattern.navbox_title) and cfg.marker.restart or cfg.class.navbox_odd_part
end
local liststyle_and_num = format(cfg.arg.liststyle_and_num, listnum)
local listclass_and_num = format(cfg.arg.listclass_and_num, listnum)
listCell
:css('padding', '0')
:cssText(args[cfg.arg.liststyle])
:cssText(rowstyle)
:cssText(args[liststyle_and_num])
:addClass(cfg.class.navbox_list)
:addClass(cfg.class.navbox_part .. oddEven)
:addClass(args[cfg.arg.listclass])
:addClass(args[listclass_and_num])
:tag('div')
:css('padding',
(index == 1 and args[cfg.arg.list1padding]) or args[cfg.arg.listpadding] or '0 0.25em'
)
:wikitext(processItem(listText, args[cfg.arg.nowrapitems]))
if index == 1 and args[cfg.arg.image] then
row
:tag('td')
:addClass(cfg.class.noviewer)
:addClass(cfg.class.navbox_image)
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '0 0 0 2px')
:cssText(args[cfg.arg.imagestyle])
:attr('rowspan', listnums_size)
:tag('div')
:wikitext(processItem(args[cfg.arg.image]))
end
end
-- uses this now to make the needHlistCategory correct
-- to use later for when we add list styles via navbox
local function has_list_class(htmlclass)
local class_args = { -- rough order of probability of use
cfg.arg.bodyclass, cfg.arg.listclass, cfg.arg.aboveclass,
cfg.arg.belowclass, cfg.arg.titleclass, cfg.arg.navboxclass,
cfg.arg.groupclass, cfg.arg.imageclass
}
local patterns = {
'^' .. htmlclass .. '$',
'%s' .. htmlclass .. '$',
'^' .. htmlclass .. '%s',
'%s' .. htmlclass .. '%s'
}
for _, arg in ipairs(class_args) do
for _, pattern in ipairs(patterns) do
if mw.ustring.find(args[arg] or '', pattern) then
return true
end
end
end
return false
end
local function needsHorizontalLists(border)
if border == cfg.keyword.border_subgroup or args[cfg.arg.tracking] == cfg.keyword.tracking_no then
return false
end
return not has_list_class(cfg.pattern.hlist) and not has_list_class(cfg.pattern.plainlist)
end
local function hasBackgroundColors()
for _, key in ipairs({cfg.arg.titlestyle, cfg.arg.groupstyle,
cfg.arg.basestyle, cfg.arg.abovestyle, cfg.arg.belowstyle}) do
if tostring(args[key]):find('background', 1, true) then
return true
end
end
return false
end
local function hasBorders()
for _, key in ipairs({cfg.arg.groupstyle, cfg.arg.basestyle,
cfg.arg.abovestyle, cfg.arg.belowstyle}) do
if tostring(args[key]):find('border', 1, true) then
return true
end
end
return false
end
local function isIllegible()
local styleratio = require('Module:Color contrast')._styleratio
for key, style in pairs(args) do
if tostring(key):match(cfg.pattern.style) then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(border)
local cats = {}
if needsHorizontalLists(border) then table.insert(cats, cfg.category.horizontal_lists) end
if hasBackgroundColors() then table.insert(cats, cfg.category.background_colors) end
if isIllegible() then table.insert(cats, cfg.category.illegible) end
if hasBorders() then table.insert(cats, cfg.category.borders) end
return cats
end
local function renderTrackingCategories(builder, border)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == cfg.keyword.subpage_doc or subpage == cfg.keyword.subpage_sandbox
or subpage == cfg.keyword.subpage_testcases then return end
for _, cat in ipairs(getTrackingCategories(border)) do
builder:wikitext('[[Category:' .. cat .. ']]')
end
end
local function renderMainTable(border, listnums)
local tbl = mw.html.create('table')
:addClass(cfg.class.nowraplinks)
:addClass(args[cfg.arg.bodyclass])
local state = args[cfg.arg.state]
if args[cfg.arg.title] and state ~= cfg.keyword.state_plain and state ~= cfg.keyword.state_off then
if state == cfg.keyword.state_collapsed then
state = cfg.class.collapsed
end
tbl
:addClass(cfg.class.collapsible)
:addClass(state or cfg.class.autocollapse)
end
tbl:css('border-spacing', 0)
if border == cfg.keyword.border_subgroup or border == cfg.keyword.border_none then
tbl
:addClass(cfg.class.navbox_subgroup)
:cssText(args[cfg.arg.bodystyle])
:cssText(args[cfg.arg.style])
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass(cfg.class.navbox_inner)
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args[cfg.arg.innerstyle])
renderTitleRow(tbl)
renderAboveRow(tbl)
local listnums_size = #listnums
for i, listnum in ipairs(listnums) do
renderListRow(tbl, i, listnum, listnums_size)
end
renderBelowRow(tbl)
return tbl
end
local function add_navbox_styles()
local frame = mw.getCurrentFrame()
-- This is a lambda so that it doesn't need the frame as a parameter
local function add_user_styles(templatestyles)
if templatestyles and templatestyles ~= '' then
return frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
}
end
return ''
end
-- get templatestyles. load base from config so that Lua only needs to do
-- the work once of parser tag expansion
local base_templatestyles = cfg.templatestyles
local templatestyles = add_user_styles(args[cfg.arg.templatestyles])
local child_templatestyles = add_user_styles(args[cfg.arg.child_templatestyles])
-- The 'navbox-styles' div exists for two reasons:
-- 1. To wrap the styles to work around T200206 more elegantly. Instead
-- of combinatorial rules, this ends up being linear number of CSS rules.
-- 2. To allow MobileFrontend to rip the styles out with 'nomobile' such that
-- they are not dumped into the mobile view.
return mw.html.create('div')
:addClass(cfg.class.navbox_styles)
:addClass(cfg.class.nomobile)
:wikitext(base_templatestyles .. templatestyles .. child_templatestyles)
:done()
end
function p._navbox(navboxArgs)
args = navboxArgs
local listnums = {}
for k, _ in pairs(args) do
if type(k) == 'string' then
local listnum = k:match(cfg.pattern.listnum)
if listnum then table.insert(listnums, tonumber(listnum)) end
end
end
table.sort(listnums)
local border = mw.text.trim(args[cfg.arg.border] or args[1] or '')
if border == cfg.keyword.border_child then
border = cfg.keyword.border_subgroup
end
-- render the main body of the navbox
local tbl = renderMainTable(border, listnums)
local res = mw.html.create()
-- render the appropriate wrapper for the navbox, based on the border param
if border == cfg.keyword.border_none then
res:node(add_navbox_styles())
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args[cfg.arg.title] or args[cfg.arg.above] or (args[cfg.arg.group1]
and not args[cfg.arg.group2]) then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(
args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1]
)
)
else
nav:attr('aria-label', cfg.aria_label)
end
elseif border == cfg.keyword.border_subgroup then
-- We assume that this navbox is being rendered in a list cell of a
-- parent navbox, and is therefore inside a div with padding:0em 0.25em.
-- We start with a </div> to avoid the padding being applied, and at the
-- end add a <div> to balance out the parent's </div>
res
:wikitext('</div>')
:node(tbl)
:wikitext('<div>')
else
res:node(add_navbox_styles())
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass(cfg.class.navbox)
:addClass(args[cfg.arg.navboxclass])
:cssText(args[cfg.arg.bodystyle])
:cssText(args[cfg.arg.style])
:css('padding', '3px')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args[cfg.arg.title] or args[cfg.arg.above]
or (args[cfg.arg.group1] and not args[cfg.arg.group2]) then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1])
)
else
nav:attr('aria-label', cfg.aria_label)
end
end
if (args[cfg.arg.nocat] or cfg.keyword.nocat_false):lower() == cfg.keyword.nocat_false then
renderTrackingCategories(res, border)
end
return striped(tostring(res), border)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
args = getArgs(frame, {wrappers = {cfg.pattern.navbox}})
-- Read the arguments in the order they'll be output in, to make references
-- number in the right order.
local _
_ = args[cfg.arg.title]
_ = args[cfg.arg.above]
-- Limit this to 20 as covering 'most' cases (that's a SWAG) and because
-- iterator approach won't work here
for i = 1, 20 do
_ = args[format(cfg.arg.group_and_num, i)]
_ = args[format(cfg.arg.list_and_num, i)]
end
_ = args[cfg.arg.below]
return p._navbox(args)
end
return p
5bbd6589b208bd567b351b855083c132c16a0fb9
Module:Navbox/configuration
828
114
243
2022-01-07T21:39:52Z
Canopus >Izno
0
remove titlegroup
Scribunto
text/plain
return {
aria_label = 'Navbox',
nowrap_item = '%s<span class="nowrap">%s</span>',
templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Module:Navbox/styles.css' }
},
-- do not localize marker table
marker = {
oddeven = '\127_ODDEVEN_\127',
restart = '\127_ODDEVEN0_\127',
regex = '\127_ODDEVEN(%d?)_\127'
},
category = {
orphan = '[[Category:Navbox orphans]]',
horizontal_lists = 'Navigational boxes without horizontal lists',
background_colors = 'Navboxes using background colours',
illegible = 'Potentially illegible navboxes',
borders = 'Navboxes using borders',
},
keyword = {
border_subgroup = 'subgroup',
border_child = 'child',
border_none = 'none',
evenodd_swap = 'swap',
navbar_off = 'off',
navbar_plain = 'plain',
nocat_false = 'false',
nowrapitems_yes = 'yes',
orphan_yes = 'yes',
state_collapsed = 'collapsed',
state_off = 'off',
state_plain = 'plain',
subpage_doc = 'doc',
subpage_sandbox = 'sandbox',
subpage_testcases = 'testcases',
tracking_no = 'no'
},
class = {
autocollapse = 'autocollapse',
collapsible = 'mw-collapsible',
collapsed = 'mw-collapsed',
-- Warning
navbox = 'navbox', -- WMF currently hides 'navbox' from mobile,
-- so you probably shouldn't change the navbox class.
navbox_abovebelow = 'navbox-abovebelow',
navbox_group = 'navbox-group',
navbox_image = 'navbox-image',
navbox_inner = 'navbox-inner',
navbox_list = 'navbox-list',
navbox_list_with_group = 'navbox-list-with-group',
navbox_part = 'navbox-', -- do not l10n
navbox_styles = 'navbox-styles',
navbox_subgroup = 'navbox-subgroup',
navbox_title = 'navbox-title', -- l10n only if you change pattern.navbox_title below
navbox_odd_part = 'odd', -- do not l10n
navbox_even_part = 'even', -- do not l10n
nomobile = 'nomobile',
nowraplinks = 'nowraplinks',
noviewer = 'noviewer' -- used to remove images from MediaViewer
},
pattern = {
listnum = '^list(%d+)$',
sandbox = '/sandbox$',
navbox = 'Template:Navbox',
nowrap = '^<span class="nowrap">',
style = 'style$',
navbox_title = '<th[^>]*"navbox%-title"',
hlist = 'hlist',
plainlist = 'plainlist'
},
arg = {
above = 'above',
aboveclass = 'aboveclass',
abovestyle = 'abovestyle',
basestyle = 'basestyle',
bodyclass = 'bodyclass',
bodystyle = 'bodystyle',
border = 'border',
below = 'below',
belowclass = 'belowclass',
belowstyle = 'belowstyle',
evenodd = 'evenodd',
evenstyle = 'evenstyle',
group1 = 'group1',
group2 = 'group2',
group_and_num = 'group%d',
groupstyle_and_num = 'group%dstyle',
groupclass = 'groupclass',
groupstyle = 'groupstyle',
groupwidth = 'groupwidth',
innerstyle = 'innerstyle',
image = 'image',
imageclass = 'imageclass',
imageleft = 'imageleft',
imageleftstyle = 'imageleftstyle',
imagesetyle = 'imagestyle',
list_and_num = 'list%d',
listclass_and_num = 'list%dclass',
liststyle_and_num = 'list%dstyle',
list1padding = 'list1padding',
listclass = 'listclass',
listpadding = 'listpadding',
liststyle = 'liststyle',
name = 'name',
navbar = 'navbar',
navboxclass = 'navboxclass',
nocat = 'nocat',
nowrapitems = 'nowrapitems',
oddstyle = 'oddstyle',
orphan = 'orphan',
state = 'state',
style = 'style',
templatestyles = 'templatestyles',
child_templatestyles = 'child templatestyles',
title = 'title',
titleclass = 'titleclass',
titlestyle = 'titlestyle',
tracking = 'tracking'
},
-- names of navbar arguments
navbar = {
name = 1,
fontstyle = 'fontstyle',
mini = 'mini'
}
}
4a1fb97efbf7aa8a852959457b43eab420073194
Module:Format link
828
106
227
2022-01-09T02:48:07Z
Canopus >Hike395
0
incorrect entry point
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Format link
--
-- Makes a wikilink from the given link and display values. Links are escaped
-- with colons if necessary, and links to sections are detected and displayed
-- with " § " as a separator rather than the standard MediaWiki "#". Used in
-- the {{format link}} template.
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- lazily initialise [[Module:Arguments]]
local mError -- lazily initialise [[Module:Error]]
local yesno -- lazily initialise [[Module:Yesno]]
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getArgs(frame)
-- Fetches the arguments from the parent frame. Whitespace is trimmed and
-- blanks are removed.
mArguments = require('Module:Arguments')
return mArguments.getArgs(frame, {parentOnly = true})
end
local function removeInitialColon(s)
-- Removes the initial colon from a string, if present.
return s:match('^:?(.*)')
end
local function maybeItalicize(s, shouldItalicize)
-- Italicize s if s is a string and the shouldItalicize parameter is true.
if s and shouldItalicize then
return '<i>' .. s .. '</i>'
else
return s
end
end
local function parseLink(link)
-- Parse a link and return a table with the link's components.
-- These components are:
-- - link: the link, stripped of any initial colon (always present)
-- - page: the page name (always present)
-- - section: the page name (may be nil)
-- - display: the display text, if manually entered after a pipe (may be nil)
link = removeInitialColon(link)
-- Find whether a faux display value has been added with the {{!}} magic
-- word.
local prePipe, display = link:match('^(.-)|(.*)$')
link = prePipe or link
-- Find the page, if it exists.
-- For links like [[#Bar]], the page will be nil.
local preHash, postHash = link:match('^(.-)#(.*)$')
local page
if not preHash then
-- We have a link like [[Foo]].
page = link
elseif preHash ~= '' then
-- We have a link like [[Foo#Bar]].
page = preHash
end
-- Find the section, if it exists.
local section
if postHash and postHash ~= '' then
section = postHash
end
return {
link = link,
page = page,
section = section,
display = display,
}
end
local function formatDisplay(parsed, options)
-- Formats a display string based on a parsed link table (matching the
-- output of parseLink) and an options table (matching the input options for
-- _formatLink).
local page = maybeItalicize(parsed.page, options.italicizePage)
local section = maybeItalicize(parsed.section, options.italicizeSection)
if (not section) then
return page
elseif (not page) then
return mw.ustring.format('§ %s', section)
else
return mw.ustring.format('%s § %s', page, section)
end
end
local function missingArgError(target)
mError = require('Module:Error')
return mError.error{message =
'Error: no link or target specified! ([[' .. target .. '#Errors|help]])'
}
end
--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------
function p.formatLink(frame)
-- The formatLink export function, for use in templates.
yesno = require('Module:Yesno')
local args = getArgs(frame)
local link = args[1] or args.link
local target = args[3] or args.target
if not (link or target) then
return missingArgError('Template:Format link')
end
return p._formatLink{
link = link,
display = args[2] or args.display,
target = target,
italicizePage = yesno(args.italicizepage),
italicizeSection = yesno(args.italicizesection),
categorizeMissing = args.categorizemissing
}
end
function p._formatLink(options)
-- The formatLink export function, for use in modules.
checkType('_formatLink', 1, options, 'table')
local function check(key, expectedType) --for brevity
checkTypeForNamedArg(
'_formatLink', key, options[key], expectedType or 'string', true
)
end
check('link')
check('display')
check('target')
check('italicizePage', 'boolean')
check('italicizeSection', 'boolean')
check('categorizeMissing')
-- Normalize link and target and check that at least one is present
if options.link == '' then options.link = nil end
if options.target == '' then options.target = nil end
if not (options.link or options.target) then
return missingArgError('Module:Format link')
end
local parsed = parseLink(options.link)
local display = options.display or parsed.display
local catMissing = options.categorizeMissing
local category = ''
-- Find the display text
if not display then display = formatDisplay(parsed, options) end
-- Handle the target option if present
if options.target then
local parsedTarget = parseLink(options.target)
parsed.link = parsedTarget.link
parsed.page = parsedTarget.page
end
-- Test if page exists if a diagnostic category is specified
if catMissing and (mw.ustring.len(catMissing) > 0) then
local title = nil
if parsed.page then title = mw.title.new(parsed.page) end
if title and (not title.isExternal) and (not title.exists) then
category = mw.ustring.format('[[Category:%s]]', catMissing)
end
end
-- Format the result as a link
if parsed.link == display then
return mw.ustring.format('[[:%s]]%s', parsed.link, category)
else
return mw.ustring.format('[[:%s|%s]]%s', parsed.link, display, category)
end
end
--------------------------------------------------------------------------------
-- Derived convenience functions
--------------------------------------------------------------------------------
function p.formatPages(options, pages)
-- Formats an array of pages using formatLink and the given options table,
-- and returns it as an array. Nil values are not allowed.
local ret = {}
for i, page in ipairs(pages) do
ret[i] = p._formatLink{
link = page,
categorizeMissing = options.categorizeMissing,
italicizePage = options.italicizePage,
italicizeSection = options.italicizeSection
}
end
return ret
end
return p
b1a3177dc2ec780dc0a9720bfb64058aed46db95
Module:Citation/CS1/styles.css
828
57
129
2022-01-22T14:11:09Z
Canopus >Trappist the monk
0
update per [[Wikipedia:Village_pump_(proposals)#rfc:_shall_we_update_cs1/2?|RfC]];
text
text/plain
/* Protection icon
the following line controls the page-protection icon in the upper right corner
it must remain within this comment
{{sandbox other||{{pp-template}}}}
*/
/* Overrides
Some wikis do not override user agent default styles for HTML <cite> and <q>,
unlike en.wp. On en.wp, keep these the same as [[MediaWiki:Common.css]].
The word-wrap and :target styles were moved here from Common.css.
On en.wp, keep these the same as [[Template:Citation/styles.css]].
*/
cite.citation {
font-style: inherit; /* Remove italics for <cite> */
/* Break long urls, etc., rather than overflowing box */
word-wrap: break-word;
}
.citation q {
quotes: '"' '"' "'" "'"; /* Straight quote marks for <q> */
}
/* Highlight linked elements (such as clicked references) in blue */
.citation:target {
/* ignore the linter - all browsers of interest implement this */
background-color: rgba(0, 127, 255, 0.133);
}
/* ID and URL access
Both core and Common.css have selector .mw-parser-output a[href$=".pdf"].external
for PDF pages. All TemplateStyles pages are hoisted to .mw-parser-output. We need
to have specificity equal to a[href$=".pdf"].external for locks to override PDF icon.
That's essentially 2 classes and 1 element.
the .id-lock-... selectors are for use by non-citation templates like
{{Catalog lookup link}} which do not have to handle PDF links
*/
.id-lock-free a,
.citation .cs1-lock-free a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/6/65/Lock-green.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-limited a,
.id-lock-registration a,
.citation .cs1-lock-limited a,
.citation .cs1-lock-registration a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/d/d6/Lock-gray-alt-2.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-subscription a,
.citation .cs1-lock-subscription a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/a/aa/Lock-red-alt-2.svg)
right 0.1em center/9px no-repeat;
}
/* Wikisource
Wikisource icon when |chapter= or |title= is wikilinked to Wikisource
as in cite wikisource
*/
.cs1-ws-icon a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/4/4c/Wikisource-logo.svg)
right 0.1em center/12px no-repeat;
}
/* Errors and maintenance */
.cs1-code {
/* <code>...</code> style override: mediawiki's css definition is specified here:
https://git.wikimedia.org/blob/mediawiki%2Fcore.git/
69cd73811f7aadd093050dbf20ed70ef0b42a713/skins%2Fcommon%2FcommonElements.css#L199
*/
color: inherit;
background: inherit;
border: none;
padding: inherit;
}
.cs1-hidden-error {
display: none;
color: #d33;
}
.cs1-visible-error {
color: #d33;
}
.cs1-maint {
display: none;
color: #3a3;
margin-left: 0.3em;
}
/* Small text size
Set small text size in one place. 0.95 (here) * 0.9 (from references list) is
~0.85, which is the lower bound for size for accessibility. Old styling for this
was just 0.85. We could write the rule so that when this template is inside
references/reflist, only then does it multiply by 0.95; else multiply by 0.85 */
.cs1-format {
font-size: 95%;
}
/* kerning */
.cs1-kern-left {
padding-left: 0.2em;
}
.cs1-kern-right {
padding-right: 0.2em;
}
/* selflinks – avoid bold font style when cs1|2 template links to the current page */
.citation .mw-selflink {
font-weight: inherit;
}
016143e761e7a41b22296023b6119ee97303dabb
Module:Citation/CS1/COinS
828
56
127
2022-01-22T14:11:14Z
Canopus >Trappist the monk
0
update per [[Wikipedia:Village_pump_(proposals)#rfc:_shall_we_update_cs1/2?|RfC]];
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup; -- functions in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< M A K E _ C O I N S _ T I T L E >----------------------------------------------
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn't corrupted with strings
of %27%27...
]]
local function make_coins_title (title, script)
title = has_accept_as_written (title);
if is_set (title) then
title = strip_apostrophe_markup (title); -- strip any apostrophe markup
else
title = ''; -- if not set, make sure title is an empty string
end
if is_set (script) then
script = script:gsub ('^%l%l%s*:%s*', ''); -- remove language prefix if present (script value may now be empty string)
script = strip_apostrophe_markup (script); -- strip any apostrophe markup
else
script = ''; -- if not set, make sure script is an empty string
end
if is_set (title) and is_set (script) then
script = ' ' .. script; -- add a space before we concatenate
end
return title .. script; -- return the concatenation
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of Lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other Lua magic pattern characters
return argument;
end
--[[--------------------------< G E T _ C O I N S _ P A G E S >------------------------------------------------
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.
]]
local function get_coins_pages (pages)
local pattern;
if not is_set (pages) then return pages; end -- if no page numbers then we're done
while true do
pattern = pages:match("%[(%w*:?//[^ ]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the URL and following space(s): "[url "
if nil == pattern then break; end -- no more URLs
pattern = escape_lua_magic_chars (pattern); -- pattern is not a literal string; escape Lua's magic pattern characters
pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible
end
pages = pages:gsub("[%[%]]", ""); -- remove the brackets
pages = pages:gsub("–", "-" ); -- replace endashes with hyphens
pages = pages:gsub("&%w+;", "-" ); -- and replace HTML entities (– etc.) with hyphens; do we need to replace numerical entities like   and the like?
return pages;
end
--[=[-------------------------< C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R >------------------
There are three options for math markup rendering that depend on the editor's math preference settings. These
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are
PNG images
TeX source
MathML with SVG or PNG fallback
All three are heavy with HTML and CSS which doesn't belong in the metadata.
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings
of the last editor to save the page.
This function gets the rendered form of an equation according to the editor's preference before the page is saved. It
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial
value. To replace multipe equations it is necessary to call this function from within a loop.
]=]
local function coins_replace_math_stripmarker (value)
local stripmarker = cfg.stripmarkers['math'];
local rendering = value:match (stripmarker); -- is there a math stripmarker
if not rendering then -- when value doesn't have a math stripmarker, abandon this test
return false, value;
end
rendering = mw.text.unstripNoWiki (rendering); -- convert stripmarker into rendered value (or nil? ''? when math render error)
if rendering:match ('alt="[^"]+"') then -- if PNG math option
rendering = rendering:match ('alt="([^"]+)"'); -- extract just the math text
elseif rendering:match ('$%s+.+%s+%$') then -- if TeX math option; $ is legit character that is escapes as \$
rendering = rendering:match ('$%s+(.+)%s+%$') -- extract just the math text
elseif rendering:match ('<annotation[^>]+>.+</annotation>') then -- if MathML math option
rendering = rendering:match ('<annotation[^>]+>(.+)</annotation>') -- extract just the math text
else
return false, value; -- had math stripmarker but not one of the three defined forms
end
return true, value:gsub (stripmarker, rendering, 1);
end
--[[--------------------------< C O I N S _ C L E A N U P >----------------------------------------------------
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.
2015-12-10: there is a bug in mw.text.unstripNoWiki (). It replaces math stripmarkers with the appropriate content
when it shouldn't. See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible
characters table?
]]
local function coins_cleanup (value)
local replaced = true; -- default state to get the do loop running
while replaced do -- loop until all math stripmarkers replaced
replaced, value = coins_replace_math_stripmarker (value); -- replace math stripmarker with text representation of the equation
end
value = value:gsub (cfg.stripmarkers['math'], "MATH RENDER ERROR"); -- one or more couldn't be replaced; insert vague error message
value = mw.text.unstripNoWiki (value); -- replace nowiki stripmarkers with their content
value = value:gsub ('<span class="nowrap" style="padding%-left:0%.1em;">'(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s
value = value:gsub (' ', ' '); -- replace entity with plain space
value = value:gsub ('\226\128\138', ' '); -- replace hair space with plain space
if not mw.ustring.find (value, cfg.indic_script) then -- don't remove zero-width joiner characters from indic script
value = value:gsub ('‍', ''); -- remove ‍ entities
value = mw.ustring.gsub (value, '[\226\128\141\226\128\139\194\173]', ''); -- remove zero-width joiner, zero-width space, soft hyphen
end
value = value:gsub ('[\009\010\013 ]+', ' '); -- replace horizontal tab, line feed, carriage return with plain space
return value;
end
--[[--------------------------< C O I N S >--------------------------------------------------------------------
COinS metadata (see <http://ocoins.info/>) allows automated tools to parse the citation information.
]]
local function COinS(data, class)
if 'table' ~= type(data) or nil == next(data) then
return '';
end
for k, v in pairs (data) do -- spin through all of the metadata parameter values
if 'ID_list' ~= k and 'Authors' ~= k then -- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)
data[k] = coins_cleanup (v);
end
end
local ctx_ver = "Z39.88-2004";
-- treat table strictly as an array with only set values.
local OCinSoutput = setmetatable( {}, {
__newindex = function(self, key, value)
if is_set(value) then
rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( remove_wiki_link( value ) ) } );
end
end
});
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'ssrn', 'journal', 'news', 'magazine'}) or (in_array (class, {'conference', 'interview', 'map', 'press release', 'web'}) and is_set(data.Periodical)) or
('citation' == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; -- journal metadata identifier
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) then -- set genre according to the type of citation template we are rendering
OCinSoutput["rft.genre"] = "preprint"; -- cite arxiv, cite biorxiv, cite citeseerx, cite ssrn
elseif 'conference' == class then
OCinSoutput["rft.genre"] = "conference"; -- cite conference (when Periodical set)
elseif 'web' == class then
OCinSoutput["rft.genre"] = "unknown"; -- cite web (when Periodical set)
else
OCinSoutput["rft.genre"] = "article"; -- journal and other 'periodical' articles
end
OCinSoutput["rft.jtitle"] = data.Periodical; -- journal only
OCinSoutput["rft.atitle"] = data.Title; -- 'periodical' article titles
-- these used only for periodicals
OCinSoutput["rft.ssn"] = data.Season; -- keywords: winter, spring, summer, fall
OCinSoutput["rft.quarter"] = data.Quarter; -- single digits 1->first quarter, etc.
OCinSoutput["rft.chron"] = data.Chron; -- free-form date components
OCinSoutput["rft.volume"] = data.Volume; -- does not apply to books
OCinSoutput["rft.issue"] = data.Issue;
OCinSoutput["rft.pages"] = data.Pages; -- also used in book metadata
elseif 'thesis' ~= class then -- all others except cite thesis are treated as 'book' metadata; genre distinguishes
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; -- book metadata identifier
if 'report' == class or 'techreport' == class then -- cite report and cite techreport
OCinSoutput["rft.genre"] = "report";
elseif 'conference' == class then -- cite conference when Periodical not set
OCinSoutput["rft.genre"] = "conference";
OCinSoutput["rft.atitle"] = data.Chapter; -- conference paper as chapter in proceedings (book)
elseif in_array (class, {'book', 'citation', 'encyclopaedia', 'interview', 'map'}) then
if is_set (data.Chapter) then
OCinSoutput["rft.genre"] = "bookitem";
OCinSoutput["rft.atitle"] = data.Chapter; -- book chapter, encyclopedia article, interview in a book, or map title
else
if 'map' == class or 'interview' == class then
OCinSoutput["rft.genre"] = 'unknown'; -- standalone map or interview
else
OCinSoutput["rft.genre"] = 'book'; -- book and encyclopedia
end
end
else -- {'audio-visual', 'AV-media-notes', 'DVD-notes', 'episode', 'interview', 'mailinglist', 'map', 'newsgroup', 'podcast', 'press release', 'serial', 'sign', 'speech', 'web'}
OCinSoutput["rft.genre"] = "unknown";
end
OCinSoutput["rft.btitle"] = data.Title; -- book only
OCinSoutput["rft.place"] = data.PublicationPlace; -- book only
OCinSoutput["rft.series"] = data.Series; -- book only
OCinSoutput["rft.pages"] = data.Pages; -- book, journal
OCinSoutput["rft.edition"] = data.Edition; -- book only
OCinSoutput["rft.pub"] = data.PublisherName; -- book and dissertation
else -- cite thesis
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:dissertation"; -- dissertation metadata identifier
OCinSoutput["rft.title"] = data.Title; -- dissertation (also patent but that is not yet supported)
OCinSoutput["rft.degree"] = data.Degree; -- dissertation only
OCinSoutput['rft.inst'] = data.PublisherName; -- book and dissertation
end
-- NB. Not currently supported are "info:ofi/fmt:kev:mtx:patent", "info:ofi/fmt:kev:mtx:dc", "info:ofi/fmt:kev:mtx:sch_svc", "info:ofi/fmt:kev:mtx:ctx"
-- and now common parameters (as much as possible)
OCinSoutput["rft.date"] = data.Date; -- book, journal, dissertation
for k, v in pairs( data.ID_list ) do -- what to do about these? For now assume that they are common to all?
if k == 'ISBN' then v = v:gsub( "[^-0-9X]", "" ); end
local id = cfg.id_handlers[k].COinS;
if string.sub( id or "", 1, 4 ) == 'info' then -- for ids that are in the info:registry
OCinSoutput["rft_id"] = table.concat{ id, "/", v };
elseif string.sub (id or "", 1, 3 ) == 'rft' then -- for isbn, issn, eissn, etc. that have defined COinS keywords
OCinSoutput[ id ] = v;
elseif 'url' == id then -- for urls that are assembled in ~/Identifiers; |asin= and |ol=
OCinSoutput["rft_id"] = table.concat ({data.ID_list[k], "#id-name=", cfg.id_handlers[k].label});
elseif id then -- when cfg.id_handlers[k].COinS is not nil so urls created here
OCinSoutput["rft_id"] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or '', "#id-name=", cfg.id_handlers[k].label }; -- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)
end
end
local last, first;
for k, v in ipairs( data.Authors ) do
last, first = coins_cleanup (v.last), coins_cleanup (v.first or ''); -- replace any nowiki stripmarkers, non-printing or invisible characters
if k == 1 then -- for the first author name only
if is_set(last) and is_set(first) then -- set these COinS values if |first= and |last= specify the first author name
OCinSoutput["rft.aulast"] = last; -- book, journal, dissertation
OCinSoutput["rft.aufirst"] = first; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation -- otherwise use this form for the first name
end
else -- for all other authors
if is_set(last) and is_set(first) then
OCinSoutput["rft.au"] = table.concat{ last, ", ", first }; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation
end
-- TODO: At present we do not report "et al.". Add anything special if this condition applies?
end
end
OCinSoutput.rft_id = data.URL;
OCinSoutput.rfr_id = table.concat{ "info:sid/", mw.site.server:match( "[^/]*$" ), ":", data.RawPage };
-- TODO: Add optional extra info:
-- rfr_dat=#REVISION<version> (referrer private data)
-- ctx_id=<data.RawPage>#<ref> (identifier for the context object)
-- ctx_tim=<ts> (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)
-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)
OCinSoutput = setmetatable( OCinSoutput, nil );
-- sort with version string always first, and combine.
-- table.sort( OCinSoutput );
table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"
return table.concat(OCinSoutput, "&");
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
remove_wiki_link = utilities_page_ptr.remove_wiki_link;
strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
make_coins_title = make_coins_title,
get_coins_pages = get_coins_pages,
COinS = COinS,
set_selected_modules = set_selected_modules,
}
54a5c6fce3535cf48f207524439635ed96505a13
Module:Citation/CS1/Utilities
828
53
121
2022-01-22T14:11:16Z
Canopus >Trappist the monk
0
update per [[Wikipedia:Village_pump_(proposals)#rfc:_shall_we_update_cs1/2?|RfC]];
Scribunto
text/plain
local z = {
error_cats_t = {}; -- for categorizing citations that contain errors
error_ids_t = {}; -- list of error identifiers; used to prevent duplication of certain errors; local to this module
error_msgs_t = {}; -- sequence table of error messages
maint_cats_t = {}; -- for categorizing citations that aren't erroneous per se, but could use a little work
prop_cats_t = {}; -- for categorizing citations based on certain properties, language of source for instance
prop_keys_t = {}; -- for adding classes to the citation's <cite> tag
};
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
]]
local function is_set (var)
return not (var == nil or var == '');
end
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
Whether needle is in haystack
]]
local function in_array (needle, haystack)
if needle == nil then
return false;
end
for n, v in ipairs (haystack) do
if v == needle then
return n;
end
end
return false;
end
--[[--------------------------< H A S _ A C C E P T _ A S _ W R I T T E N >------------------------------------
When <str> is wholly wrapped in accept-as-written markup, return <str> without markup and true; return <str> and false else
with allow_empty = false, <str> must have at least one character inside the markup
with allow_empty = true, <str> the markup frame can be empty like (()) to distinguish an empty template parameter from the specific condition "has no applicable value" in citation-context.
After further evaluation the two cases might be merged at a later stage, but should be kept separated for now.
]]
local function has_accept_as_written (str, allow_empty)
if not is_set (str) then
return str, false;
end
local count;
if true == allow_empty then
str, count = str:gsub ('^%(%((.*)%)%)$', '%1'); -- allows (()) to be an empty set
else
str, count = str:gsub ('^%(%((.+)%)%)$', '%1');
end
return str, 0 ~= count;
end
--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------
Populates numbered arguments in a message string using an argument table. <args> may be a single string or a
sequence table of multiple strings.
]]
local function substitute (msg, args)
return args and mw.message.newRawMessage (msg, args):plain() or msg;
end
--[[--------------------------< E R R O R _ C O M M E N T >----------------------------------------------------
Wraps error messages with CSS markup according to the state of hidden. <content> may be a single string or a
sequence table of multiple strings.
]]
local function error_comment (content, hidden)
return substitute (hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content);
end
--[[--------------------------< H Y P H E N _ T O _ D A S H >--------------------------------------------------
Converts a hyphen to a dash under certain conditions. The hyphen must separate
like items; unlike items are returned unmodified. These forms are modified:
letter - letter (A - B)
digit - digit (4-5)
digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
letterdigit - letterdigit (A1-A5) (an optional separator between letter and
digit is supported – a.1-a.5 or a-1-a-5)
digitletter - digitletter (5a - 5d) (an optional separator between letter and
digit is supported – 5.a-5.d or 5-a-5-d)
any other forms are returned unmodified.
str may be a comma- or semicolon-separated list
]]
local function hyphen_to_dash (str)
if not is_set (str) then
return str;
end
local accept; -- boolean
str = str:gsub ("(%(%(.-%)%))", function(m) return m:gsub(",", ","):gsub(";", ";") end) -- replace commas and semicolons in accept-as-written markup with similar unicode characters so they'll be ignored during the split
str = str:gsub ('&[nm]dash;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace HTML numeric entity with hyphen character
str = str:gsub (' ', ' '); -- replace entity with generic keyboard space character
local out = {};
local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any
for _, item in ipairs (list) do -- for each item in the list
item, accept = has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item
if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators
if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit)
item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter)
item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit
item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit
item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter
item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters
else
item = mw.ustring.gsub (item, '%s*[–—]%s*', '–'); -- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace
end
end
table.insert (out, item); -- add the (possibly modified) item to the output table
end
local temp_str = ''; -- concatenate the output table into a comma separated string
temp_str, accept = has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out
if accept then
temp_str = has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value
return temp_str:gsub(",", ","):gsub(";", ";");
else
return temp_str:gsub(",", ","):gsub(";", ";"); -- else, return assembled temp_str
end
end
--[=[-------------------------< M A K E _ W I K I L I N K >----------------------------------------------------
Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only
link is provided (or link and display are the same), returns a wikilink in the form [[L]]; if neither are
provided or link is omitted, returns an empty string.
]=]
local function make_wikilink (link, display)
if not is_set (link) then return '' end
if is_set (display) and link ~= display then
return table.concat ({'[[', link, '|', display, ']]'});
else
return table.concat ({'[[', link, ']]'});
end
end
--[[--------------------------< S E T _ M E S S A G E >----------------------------------------------------------
Sets an error message using the ~/Configuration error_conditions{} table along with arguments supplied in the function
call, inserts the resulting message in z.error_msgs_t{} sequence table, and returns the error message.
<error_id> – key value for appropriate error handler in ~/Configuration error_conditions{} table
<arguments> – may be a single string or a sequence table of multiple strings to be subsititued into error_conditions[error_id].message
<raw> – boolean
true – causes this function to return the error message not wrapped in visible-error, hidden-error span tag;
returns error_conditions[error_id].hidden as a second return value
does not add message to z.error_msgs_t sequence table
false, nil – adds message wrapped in visible-error, hidden-error span tag to z.error_msgs_t
returns the error message wrapped in visible-error, hidden-error span tag; there is no second return value
<prefix> – string to be prepended to <message> -- TODO: remove support for these unused(?) arguments?
<suffix> – string to be appended to <message>
TODO: change z.error_cats_t and z.maint_cats_t to have the form cat_name = true? this to avoid dups without having to have an extra table
]]
local added_maint_cats = {} -- list of maintenance categories that have been added to z.maint_cats_t; TODO: figure out how to delete this table
local function set_message (error_id, arguments, raw, prefix, suffix)
local error_state = cfg.error_conditions[error_id];
prefix = prefix or '';
suffix = suffix or '';
if error_state == nil then
error (cfg.messages['undefined_error'] .. ': ' .. error_id); -- because missing error handler in Module:Citation/CS1/Configuration
elseif is_set (error_state.category) then
if error_state.message then -- when error_state.message defined, this is an error message
table.insert (z.error_cats_t, error_state.category);
else
if not added_maint_cats[error_id] then
added_maint_cats[error_id] = true; -- note that we've added this category
table.insert (z.maint_cats_t, substitute (error_state.category, arguments)); -- make cat name then add to table
end
return; -- because no message, nothing more to do
end
end
local message = substitute (error_state.message, arguments);
message = table.concat (
{
message,
' (',
make_wikilink (
table.concat (
{
cfg.messages['help page link'],
'#',
error_state.anchor
}),
cfg.messages['help page label']),
')'
});
z.error_ids_t[error_id] = true;
if z.error_ids_t['err_citation_missing_title'] and -- if missing-title error already noted
in_array (error_id, {'err_bare_url_missing_title', 'err_trans_missing_title'}) then -- and this error is one of these
return '', false; -- don't bother because one flavor of missing title is sufficient
end
message = table.concat ({prefix, message, suffix});
if true == raw then
return message, error_state.hidden; -- return message not wrapped in visible-error, hidden-error span tag
end
message = error_comment (message, error_state.hidden); -- wrap message in visible-error, hidden-error span tag
table.insert (z.error_msgs_t, message); -- add it to the messages sequence table
return message; -- and done; return value generally not used but is used as a flag in various functions of ~/Identifiers
end
--[[-------------------------< I S _ A L I A S _ U S E D >-----------------------------------------------------
This function is used by select_one() to determine if one of a list of alias parameters is in the argument list
provided by the template.
Input:
args – pointer to the arguments table from calling template
alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration
index – for enumerated parameters, identifies which one
enumerated – true/false flag used to choose how enumerated aliases are examined
value – value associated with an alias that has previously been selected; nil if not yet selected
selected – the alias that has previously been selected; nil if not yet selected
error_list – list of aliases that are duplicates of the alias already selected
Returns:
value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected
selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected
]]
local function is_alias_used (args, alias, index, enumerated, value, selected, error_list)
if enumerated then -- is this a test for an enumerated parameters?
alias = alias:gsub ('#', index); -- replace '#' with the value in index
else
alias = alias:gsub ('#', ''); -- remove '#' if it exists
end
if is_set (args[alias]) then -- alias is in the template's argument list
if value ~= nil and selected ~= alias then -- if we have already selected one of the aliases
local skip;
for _, v in ipairs (error_list) do -- spin through the error list to see if we've added this alias
if v == alias then
skip = true;
break; -- has been added so stop looking
end
end
if not skip then -- has not been added so
table.insert (error_list, alias); -- add error alias to the error list
end
else
value = args[alias]; -- not yet selected an alias, so select this one
selected = alias;
end
end
return value, selected; -- return newly selected alias, or previously selected alias
end
--[[--------------------------< A D D _ M A I N T _ C A T >------------------------------------------------------
Adds a category to z.maint_cats_t using names from the configuration file with additional text if any.
To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maint_cats_t.
]]
local function add_maint_cat (key, arguments)
if not added_maint_cats [key] then
added_maint_cats [key] = true; -- note that we've added this category
table.insert (z.maint_cats_t, substitute (cfg.maint_cats [key], arguments)); -- make name then add to table
end
end
--[[--------------------------< A D D _ P R O P _ C A T >--------------------------------------------------------
Adds a category to z.prop_cats_t using names from the configuration file with additional text if any.
foreign_lang_source and foreign_lang_source_2 keys have a language code appended to them so that multiple languages
may be categorized but multiples of the same language are not categorized.
added_prop_cats is a table declared in page scope variables above
]]
local added_prop_cats = {}; -- list of property categories that have been added to z.prop_cats_t
local function add_prop_cat (key, arguments, key_modifier)
local key_modified = key .. ((key_modifier and key_modifier) or ''); -- modify <key> with <key_modifier> if present and not nil
if not added_prop_cats [key_modified] then
added_prop_cats [key_modified] = true; -- note that we've added this category
table.insert (z.prop_cats_t, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table
table.insert (z.prop_keys_t, 'cs1-prop-' .. key); -- convert key to class for use in the citation's <cite> tag
end
end
--[[--------------------------< S A F E _ F O R _ I T A L I C S >----------------------------------------------
Protects a string that will be wrapped in wiki italic markup '' ... ''
Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that
they will be inverted (i.e. unitalicized) in the resulting references. In addition, <i> and '' tend to interact
poorly under Mediawiki's HTML tidy.
]]
local function safe_for_italics (str)
if not is_set (str) then return str end
if str:sub (1, 1) == "'" then str = "<span></span>" .. str; end
if str:sub (-1, -1) == "'" then str = str .. "<span></span>"; end
return str:gsub ('\n', ' '); -- Remove newlines as they break italics.
end
--[[--------------------------< W R A P _ S T Y L E >----------------------------------------------------------
Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one
argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason
this function is similar to but separate from wrap_msg().
]]
local function wrap_style (key, str)
if not is_set (str) then
return "";
elseif in_array (key, {'italic-title', 'trans-italic-title'}) then
str = safe_for_italics (str);
end
return substitute (cfg.presentation[key], {str});
end
--[[--------------------------< M A K E _ S E P _ L I S T >------------------------------------------------------------
make a separated list of items using provided separators.
<sep_list> - typically '<comma><space>'
<sep_list_pair> - typically '<space>and<space>'
<sep_list_end> - typically '<comma><space>and<space>' or '<comma><space>&<space>'
defaults to cfg.presentation['sep_list'], cfg.presentation['sep_list_pair'], and cfg.presentation['sep_list_end']
if <sep_list_end> is specified, <sep_list> and <sep_list_pair> must also be supplied
]]
local function make_sep_list (count, list_seq, sep_list, sep_list_pair, sep_list_end)
local list = '';
if not sep_list then -- set the defaults
sep_list = cfg.presentation['sep_list'];
sep_list_pair = cfg.presentation['sep_list_pair'];
sep_list_end = cfg.presentation['sep_list_end'];
end
if 2 >= count then
list = table.concat (list_seq, sep_list_pair); -- insert separator between two items; returns list_seq[1] then only one item
elseif 2 < count then
list = table.concat (list_seq, sep_list, 1, count - 1); -- concatenate all but last item with plain list separator
list = table.concat ({list, list_seq[count]}, sep_list_end); -- concatenate last item onto end of <list> with final separator
end
return list;
end
--[[--------------------------< S E L E C T _ O N E >----------------------------------------------------------
Chooses one matching parameter from a list of parameters to consider. The list of parameters to consider is just
names. For parameters that may be enumerated, the position of the numerator in the parameter name is identified
by the '#' so |author-last1= and |author1-last= are represented as 'author-last#' and 'author#-last'.
Because enumerated parameter |<param>1= is an alias of |<param>= we must test for both possibilities.
Generates an error if more than one match is present.
]]
local function select_one (args, aliases_list, error_condition, index)
local value = nil; -- the value assigned to the selected parameter
local selected = ''; -- the name of the parameter we have chosen
local error_list = {};
if index ~= nil then index = tostring(index); end
for _, alias in ipairs (aliases_list) do -- for each alias in the aliases list
if alias:match ('#') then -- if this alias can be enumerated
if '1' == index then -- when index is 1 test for enumerated and non-enumerated aliases
value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- first test for non-enumerated alias
end
value, selected = is_alias_used (args, alias, index, true, value, selected, error_list); -- test for enumerated alias
else
value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- test for non-enumerated alias
end
end
if #error_list > 0 and 'none' ~= error_condition then -- for cases where this code is used outside of extract_names()
for i, v in ipairs (error_list) do
error_list[i] = wrap_style ('parameter', v);
end
table.insert (error_list, wrap_style ('parameter', selected));
set_message (error_condition, {make_sep_list (#error_list, error_list)});
end
return value, selected;
end
--[=[-------------------------< R E M O V E _ W I K I _ L I N K >----------------------------------------------
Gets the display text from a wikilink like [[A|B]] or [[B]] gives B
The str:gsub() returns either A|B froma [[A|B]] or B from [[B]] or B from B (no wikilink markup).
In l(), l:gsub() removes the link and pipe (if they exist); the second :gsub() trims whitespace from the label
if str was wrapped in wikilink markup. Presumably, this is because without wikimarkup in str, there is no match
in the initial gsub, the replacement function l() doesn't get called.
]=]
local function remove_wiki_link (str)
return (str:gsub ("%[%[([^%[%]]*)%]%]", function(l)
return l:gsub ("^[^|]*|(.*)$", "%1" ):gsub ("^%s*(.-)%s*$", "%1");
end));
end
--[=[-------------------------< I S _ W I K I L I N K >--------------------------------------------------------
Determines if str is a wikilink, extracts, and returns the wikilink type, link text, and display text parts.
If str is a complex wikilink ([[L|D]]):
returns wl_type 2 and D and L from [[L|D]];
if str is a simple wikilink ([[D]])
returns wl_type 1 and D from [[D]] and L as empty string;
if not a wikilink:
returns wl_type 0, str as D, and L as empty string.
trims leading and trailing whitespace and pipes from L and D ([[L|]] and [[|D]] are accepted by MediaWiki and
treated like [[D]]; while [[|D|]] is not accepted by MediaWiki, here, we accept it and return D without the pipes).
]=]
local function is_wikilink (str)
local D, L
local wl_type = 2; -- assume that str is a complex wikilink [[L|D]]
if not str:match ('^%[%[[^%]]+%]%]$') then -- is str some sort of a wikilink (must have some sort of content)
return 0, str, ''; -- not a wikilink; return wl_type as 0, str as D, and empty string as L
end
L, D = str:match ('^%[%[([^|]+)|([^%]]+)%]%]$'); -- get L and D from [[L|D]]
if not is_set (D) then -- if no separate display
D = str:match ('^%[%[([^%]]*)|*%]%]$'); -- get D from [[D]] or [[D|]]
wl_type = 1;
end
D = mw.text.trim (D, '%s|'); -- trim white space and pipe characters
return wl_type, D, L or '';
end
--[[--------------------------< S T R I P _ A P O S T R O P H E _ M A R K U P >--------------------------------
Strip wiki italic and bold markup from argument so that it doesn't contaminate COinS metadata.
This function strips common patterns of apostrophe markup. We presume that editors who have taken the time to
markup a title have, as a result, provided valid markup. When they don't, some single apostrophes are left behind.
Returns the argument without wiki markup and a number; the number is more-or-less meaningless except as a flag
to indicate that markup was replaced; do not rely on it as an indicator of how many of any kind of markup was
removed; returns the argument and nil when no markup removed
]]
local function strip_apostrophe_markup (argument)
if not is_set (argument) then
return argument, nil; -- no argument, nothing to do
end
if nil == argument:find ( "''", 1, true ) then -- Is there at least one double apostrophe? If not, exit.
return argument, nil;
end
local flag;
while true do
if argument:find ("'''''", 1, true) then -- bold italic (5)
argument, flag = argument:gsub ("%'%'%'%'%'", ""); -- remove all instances of it
elseif argument:find ("''''", 1, true) then -- italic start and end without content (4)
argument, flag=argument:gsub ("%'%'%'%'", "");
elseif argument:find ("'''", 1, true) then -- bold (3)
argument, flag=argument:gsub ("%'%'%'", "");
elseif argument:find ("''", 1, true) then -- italic (2)
argument, flag = argument:gsub ("%'%'", "");
else
break;
end
end
return argument, flag; -- done
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr)
cfg = cfg_table_ptr;
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
add_maint_cat = add_maint_cat, -- exported functions
add_prop_cat = add_prop_cat,
error_comment = error_comment,
has_accept_as_written = has_accept_as_written,
hyphen_to_dash = hyphen_to_dash,
in_array = in_array,
is_set = is_set,
is_wikilink = is_wikilink,
make_sep_list = make_sep_list,
make_wikilink = make_wikilink,
remove_wiki_link = remove_wiki_link,
safe_for_italics = safe_for_italics,
select_one = select_one,
set_message = set_message,
set_selected_modules = set_selected_modules,
strip_apostrophe_markup = strip_apostrophe_markup,
substitute = substitute,
wrap_style = wrap_style,
z = z, -- exported table
}
b006801b48981b2987f20fc09cbe0dfda525e044
Module:Citation/CS1/Identifiers
828
55
125
2022-01-22T14:11:18Z
Canopus >Trappist the monk
0
update per [[Wikipedia:Village_pump_(proposals)#rfc:_shall_we_update_cs1/2?|RfC]];
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, set_message, select_one, -- functions in Module:Citation/CS1/Utilities
substitute, make_wikilink;
local z; -- table of tables defined in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< P A G E S C O P E V A R I A B L E S >--------------------------------------
declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here
]]
local auto_link_urls = {}; -- holds identifier URLs for those identifiers that can auto-link |title=
--============================<< H E L P E R F U N C T I O N S >>============================================
--[[--------------------------< W I K I D A T A _ A R T I C L E _ N A M E _ G E T >----------------------------
as an aid to internationalizing identifier-label wikilinks, gets identifier article names from Wikidata.
returns :<lang code>:<article title> when <q> has an <article title> for <lang code>; nil else
for identifiers that do not have q, returns nil
for wikis that do not have mw.wikibase installed, returns nil
]]
local function wikidata_article_name_get (q)
if not is_set (q) or (q and not mw.wikibase) then -- when no q number or when a q number but mw.wikibase not installed on this wiki
return nil; -- abandon
end
local wd_article;
local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org
wd_article = mw.wikibase.getSitelink (q, this_wiki_code .. 'wiki'); -- fetch article title from WD; nil when no title available at this wiki
if wd_article then
wd_article = table.concat ({':', this_wiki_code, ':', wd_article}); -- interwiki-style link without brackets if taken from WD; leading colon required
end
return wd_article; -- article title from WD; nil else
end
--[[--------------------------< L I N K _ L A B E L _ M A K E >------------------------------------------------
common function to create identifier link label from handler table or from Wikidata
returns the first available of
1. redirect from local wiki's handler table (if enabled)
2. Wikidata (if there is a Wikidata entry for this identifier in the local wiki's language)
3. label specified in the local wiki's handler table
]]
local function link_label_make (handler)
local wd_article;
if not (cfg.use_identifier_redirects and is_set (handler.redirect)) then -- redirect has priority so if enabled and available don't fetch from Wikidata because expensive
wd_article = wikidata_article_name_get (handler.q); -- if Wikidata has an article title for this wiki, get it;
end
return (cfg.use_identifier_redirects and is_set (handler.redirect) and handler.redirect) or wd_article or handler.link;
end
--[[--------------------------< E X T E R N A L _ L I N K _ I D >----------------------------------------------
Formats a wiki-style external link
]]
local function external_link_id (options)
local url_string = options.id;
local ext_link;
local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org
local wd_article; -- article title from Wikidata
if options.encode == true or options.encode == nil then
url_string = mw.uri.encode (url_string, 'PATH');
end
if options.auto_link and is_set (options.access) then
auto_link_urls[options.auto_link] = table.concat ({options.prefix, url_string, options.suffix});
end
ext_link = mw.ustring.format ('[%s%s%s %s]', options.prefix, url_string, options.suffix or "", mw.text.nowiki (options.id));
if is_set (options.access) then
ext_link = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[options.access].class, cfg.presentation[options.access].title, ext_link}); -- add the free-to-read / paywall lock
end
return table.concat ({
make_wikilink (link_label_make (options), options.label), -- redirect, Wikidata link, or locally specified link (in that order)
options.separator or ' ',
ext_link
});
end
--[[--------------------------< I N T E R N A L _ L I N K _ I D >----------------------------------------------
Formats a wiki-style internal link
TODO: Does not currently need to support options.access, options.encode, auto-linking and COinS (as in external_link_id),
but may be needed in the future for :m:Interwiki_map custom-prefixes like :arxiv:, :bibcode:, :DOI:, :hdl:, :ISSN:,
:JSTOR:, :Openlibrary:, :PMID:, :RFC:.
]]
local function internal_link_id (options)
local id = mw.ustring.gsub (options.id, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9
return table.concat (
{
make_wikilink (link_label_make (options), options.label), -- wiki-link the identifier label
options.separator or ' ', -- add the separator
make_wikilink (
table.concat (
{
options.prefix,
id, -- translated to Western digits
options.suffix or ''
}),
substitute (cfg.presentation['bdi'], {'', mw.text.nowiki (options.id)}) -- bdi tags to prevent Latin script identifiers from being reversed at RTL language wikis
); -- nowiki because MediaWiki still has magic links for ISBN and the like; TODO: is it really required?
});
end
--[[--------------------------< I S _ E M B A R G O E D >------------------------------------------------------
Determines if a PMC identifier's online version is embargoed. Compares the date in |pmc-embargo-date= against
today's date. If embargo date is in the future, returns the content of |pmc-embargo-date=; otherwise, returns
an empty string because the embargo has expired or because |pmc-embargo-date= was not set in this cite.
]]
local function is_embargoed (embargo)
if is_set (embargo) then
local lang = mw.getContentLanguage();
local good1, embargo_date, todays_date;
good1, embargo_date = pcall (lang.formatDate, lang, 'U', embargo);
todays_date = lang:formatDate ('U');
if good1 then -- if embargo date is a good date
if tonumber (embargo_date) >= tonumber (todays_date) then -- is embargo date is in the future?
return embargo; -- still embargoed
else
set_message ('maint_pmc_embargo'); -- embargo has expired; add main cat
return ''; -- unset because embargo has expired
end
end
end
return ''; -- |pmc-embargo-date= not set return empty string
end
--[=[-------------------------< I S _ V A L I D _ B I O R X I V _ D A T E >------------------------------------
returns true if:
2019-12-11T00:00Z <= biorxiv_date < today + 2 days
The dated form of biorxiv identifier has a start date of 2019-12-11. The Unix timestamp for that date is {{#time:U|2019-12-11}} = 1576022400
biorxiv_date is the date provided in those |biorxiv= parameter values that are dated at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
if today is 2015-01-01T00:00:00 then
adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser
apparently doesn't understand non-English date month names. This function will always return false when the date
contains a non-English month name because good1 is false after the call to lang_object.formatDate(). To get
around that call this function with date parts and create a YYYY-MM-DD format date.
]=]
local function is_valid_biorxiv_date (y, m, d)
local biorxiv_date = table.concat ({y, m, d}, '-'); -- make ymd date
local good1, good2;
local biorxiv_ts, tomorrow_ts; -- to hold Unix timestamps representing the dates
local lang_object = mw.getContentLanguage();
good1, biorxiv_ts = pcall (lang_object.formatDate, lang_object, 'U', biorxiv_date); -- convert biorxiv_date value to Unix timestamp
good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which tonumber() may not understand
biorxiv_ts = tonumber (biorxiv_ts) or lang_object:parseFormattedNumber (biorxiv_ts); -- convert to numbers for the comparison;
tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts);
else
return false; -- one or both failed to convert to Unix timestamp
end
return ((1576022400 <= biorxiv_ts) and (biorxiv_ts < tomorrow_ts)) -- 2012-12-11T00:00Z <= biorxiv_date < tomorrow's date
end
--[[--------------------------< IS _ V A L I D _ I S X N >-----------------------------------------------------
ISBN-10 and ISSN validator code calculates checksum across all ISBN/ISSN digits including the check digit.
ISBN-13 is checked in isbn().
If the number is valid the result will be 0. Before calling this function, ISBN/ISSN must be checked for length
and stripped of dashes, spaces and other non-ISxN characters.
]]
local function is_valid_isxn (isxn_str, len)
local temp = 0;
isxn_str = { isxn_str:byte(1, len) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39, 'X' → 0x58
len = len + 1; -- adjust to be a loop counter
for i, v in ipairs (isxn_str) do -- loop through all of the bytes and calculate the checksum
if v == string.byte ("X" ) then -- if checkdigit is X (compares the byte value of 'X' which is 0x58)
temp = temp + 10 * (len - i); -- it represents 10 decimal
else
temp = temp + tonumber (string.char (v) )*(len-i);
end
end
return temp % 11 == 0; -- returns true if calculation result is zero
end
--[[--------------------------< IS _ V A L I D _ I S X N _ 1 3 >-----------------------------------------------
ISBN-13 and ISMN validator code calculates checksum across all 13 ISBN/ISMN digits including the check digit.
If the number is valid, the result will be 0. Before calling this function, ISBN-13/ISMN must be checked for length
and stripped of dashes, spaces and other non-ISxN-13 characters.
]]
local function is_valid_isxn_13 (isxn_str)
local temp=0;
isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39
for i, v in ipairs (isxn_str) do
temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); -- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit
end
return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct
end
--[[--------------------------< N O R M A L I Z E _ L C C N >--------------------------------------------------
LCCN normalization (http://www.loc.gov/marc/lccn-namespace.html#normalization)
1. Remove all blanks.
2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash.
3. If there is a hyphen in the string:
a. Remove it.
b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out):
1. All these characters should be digits, and there should be six or less. (not done in this function)
2. If the length of the substring is less than 6, left-fill the substring with zeroes until the length is six.
Returns a normalized LCCN for lccn() to validate. There is no error checking (step 3.b.1) performed in this function.
]]
local function normalize_lccn (lccn)
lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace
if nil ~= string.find (lccn, '/') then
lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it
end
local prefix
local suffix
prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix
if nil ~= suffix then -- if there was a hyphen
suffix = string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6
lccn = prefix..suffix; -- reassemble the LCCN
end
return lccn;
end
--============================<< I D E N T I F I E R F U N C T I O N S >>====================================
--[[--------------------------< A R X I V >--------------------------------------------------------------------
See: http://arxiv.org/help/arxiv_identifier
format and error check arXiv identifier. There are three valid forms of the identifier:
the first form, valid only between date codes 9107 and 0703, is:
arXiv:<archive>.<class>/<date code><number><version>
where:
<archive> is a string of alpha characters - may be hyphenated; no other punctuation
<class> is a string of alpha characters - may be hyphenated; no other punctuation; not the same as |class= parameter which is not supported in this form
<date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01
first digit of YY for this form can only 9 and 0
<number> is a three-digit number
<version> is a 1 or more digit number preceded with a lowercase v; no spaces (undocumented)
the second form, valid from April 2007 through December 2014 is:
arXiv:<date code>.<number><version>
where:
<date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01
<number> is a four-digit number
<version> is a 1 or more digit number preceded with a lowercase v; no spaces
the third form, valid from January 2015 is:
arXiv:<date code>.<number><version>
where:
<date code> and <version> are as defined for 0704-1412
<number> is a five-digit number
]]
local function arxiv (options)
local id = options.id;
local class = options.Class; -- TODO: lowercase?
local handler = options.handler;
local year, month, version;
local err_msg = false; -- assume no error message
local text; -- output text
if id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%d$") or id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%dv%d+$") then -- test for the 9107-0703 format with or without version
year, month = id:match("^%a[%a%.%-]+/([90]%d)([01]%d)%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((not (90 < year or 8 > year)) or (1 > month or 12 < month)) or -- if invalid year or invalid month
((91 == year and 7 > month) or (7 == year and 3 < month)) then -- if years ok, are starting and ending months ok?
err_msg = true; -- flag for error message
end
elseif id:match("^%d%d[01]%d%.%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%dv%d+$") then -- test for the 0704-1412 with or without version
year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((7 > year) or (14 < year) or (1 > month or 12 < month)) or -- is year invalid or is month invalid? (doesn't test for future years)
((7 == year) and (4 > month)) then -- when year is 07, is month invalid (before April)?
err_msg = true; -- flag for error message
end
elseif id:match("^%d%d[01]%d%.%d%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%d%dv%d+$") then -- test for the 1501- format with or without version
year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((15 > year) or (1 > month or 12 < month)) then -- is year invalid or is month invalid? (doesn't test for future years)
err_msg = true; -- flag for error message
end
else
err_msg = true; -- not a recognized format; flag for error message
end
if err_msg then
options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS
end
local err_msg_t = {};
if err_msg then
set_message ('err_bad_arxiv');
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access});
if is_set (class) then
if id:match ('^%d+') then
text = table.concat ({text, ' [[//arxiv.org/archive/', class, ' ', class, ']]'}); -- external link within square brackets, not wikilink
else
set_message ('err_class_ignored');
end
end
return text;
end
--[[--------------------------< B I B C O D E >--------------------------------------------------------------------
Validates (sort of) and formats a bibcode ID.
Format for bibcodes is specified here: http://adsabs.harvard.edu/abs_doc/help_pages/data.html#bibcodes
But, this: 2015arXiv151206696F is apparently valid so apparently, the only things that really matter are length, 19 characters
and first four digits must be a year. This function makes these tests:
length must be 19 characters
characters in position
1–4 must be digits and must represent a year in the range of 1000 – next year
5 must be a letter
6–8 must be letter, digit, ampersand, or dot (ampersand cannot directly precede a dot; &. )
9–18 must be letter, digit, or dot
19 must be a letter or dot
]]
local function bibcode (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local err_type;
local err_msg = '';
local year;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode,
access = access});
if 19 ~= id:len() then
err_type = cfg.err_msg_supl.length;
else
year = id:match ("^(%d%d%d%d)[%a][%w&%.][%w&%.][%w&%.][%w.]+[%a%.]$");
if not year then -- if nil then no pattern match
err_type = cfg.err_msg_supl.value; -- so value error
else
local next_year = tonumber (os.date ('%Y')) + 1; -- get the current year as a number and add one for next year
year = tonumber (year); -- convert year portion of bibcode to a number
if (1000 > year) or (year > next_year) then
err_type = cfg.err_msg_supl.year; -- year out of bounds
end
if id:find('&%.') then
err_type = cfg.err_msg_supl.journal; -- journal abbreviation must not have '&.' (if it does it's missing a letter)
end
end
end
if is_set (err_type) then -- if there was an error detected
set_message ('err_bad_bibcode', {err_type});
options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< B I O R X I V >-----------------------------------------------------------------
Format bioRxiv ID and do simple error checking. Before 2019-12-11, biorXiv IDs were 10.1101/ followed by exactly
6 digits. After 2019-12-11, biorXiv IDs retained the six-digit identifier but prefixed that with a yyyy.mm.dd.
date and suffixed with an optional version identifier.
The bioRxiv ID is the string of characters:
https://doi.org/10.1101/078733 -> 10.1101/078733
or a date followed by a six-digit number followed by an optional version indicator 'v' and one or more digits:
https://www.biorxiv.org/content/10.1101/2019.12.11.123456v2 -> 10.1101/2019.12.11.123456v2
see https://www.biorxiv.org/about-biorxiv
]]
local function biorxiv (options)
local id = options.id;
local handler = options.handler;
local err_msg = true; -- flag; assume that there will be an error
local patterns = {
'^10.1101/%d%d%d%d%d%d$', -- simple 6-digit identifier (before 2019-12-11)
'^10.1101/(20[1-9]%d)%.([01]%d)%.([0-3]%d)%.%d%d%d%d%d%dv%d+$', -- y.m.d. date + 6-digit identifier + version (after 2019-12-11)
'^10.1101/(20[1-9]%d)%.([01]%d)%.([0-3]%d)%.%d%d%d%d%d%d$', -- y.m.d. date + 6-digit identifier (after 2019-12-11)
}
for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match
if id:match (pattern) then
local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier
if m then -- m is nil when id is the six-digit form
if not is_valid_biorxiv_date (y, m, d) then -- validate the encoded date; TODO: don't ignore leap-year and actual month lengths ({{#time:}} is a poor date validator)
break; -- date fail; break out early so we don't unset the error message
end
end
err_msg = nil; -- we found a match so unset the error message
break; -- and done
end
end -- err_cat remains set here when no match
if err_msg then
options.coins_list_t['BIORXIV'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_biorxiv'); -- and set the error message
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator,
encode = handler.encode, access = handler.access});
end
--[[--------------------------< C I T E S E E R X >------------------------------------------------------------
CiteSeerX use their own notion of "doi" (not to be confused with the identifiers resolved via doi.org).
The description of the structure of this identifier can be found at Help_talk:Citation_Style_1/Archive_26#CiteSeerX_id_structure
]]
local function citeseerx (options)
local id = options.id;
local handler = options.handler;
local matched;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode,
access = handler.access});
matched = id:match ("^10%.1%.1%.[1-9]%d?%d?%d?%.[1-9]%d?%d?%d?$");
if not matched then
set_message ('err_bad_citeseerx' );
options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< D O I >------------------------------------------------------------------------
Formats a DOI and checks for DOI errors.
DOI names contain two parts: prefix and suffix separated by a forward slash.
Prefix: directory indicator '10.' followed by a registrant code
Suffix: character string of any length chosen by the registrant
This function checks a DOI name for: prefix/suffix. If the DOI name contains spaces or endashes, or, if it ends
with a period or a comma, this function will emit a bad_doi error message.
DOI names are case-insensitive and can incorporate any printable Unicode characters so the test for spaces, endash,
and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely
if ever used in DOI names.
]]
local function doi (options)
local id = options.id;
local inactive = options.DoiBroken
local access = options.access;
local ignore_invalid = options.accept;
local handler = options.handler;
local err_flag;
local text;
if is_set (inactive) then
local inactive_year = inactive:match("%d%d%d%d") or ''; -- try to get the year portion from the inactive date
local inactive_month, good;
if is_set (inactive_year) then
if 4 < inactive:len() then -- inactive date has more than just a year (could be anything)
local lang_obj = mw.getContentLanguage(); -- get a language object for this wiki
good, inactive_month = pcall (lang_obj.formatDate, lang_obj, 'F', inactive); -- try to get the month name from the inactive date
if not good then
inactive_month = nil; -- something went wrong so make sure this is unset
end
end
else
inactive_year = nil; -- |doi-broken-date= has something but it isn't a date
end
if is_set (inactive_year) and is_set (inactive_month) then
set_message ('maint_doi_inactive_dated', {inactive_year, inactive_month, ' '});
elseif is_set (inactive_year) then
set_message ('maint_doi_inactive_dated', {inactive_year, '', ''});
else
set_message ('maint_doi_inactive');
end
inactive = " (" .. cfg.messages['inactive'] .. ' ' .. inactive .. ')';
end
local registrant = mw.ustring.match (id, '^10%.([^/]+)/[^%s–]-[^%.,]$'); -- registrant set when DOI has the proper basic form
local registrant_err_patterns = { -- these patterns are for code ranges that are not supported
'^[^1-3]%d%d%d%d%.%d%d*$', -- 5 digits with subcode (0xxxx, 40000+); accepts: 10000–39999
'^[^1-5]%d%d%d%d$', -- 5 digits without subcode (0xxxx, 60000+); accepts: 10000–59999
'^[^1-9]%d%d%d%.%d%d*$', -- 4 digits with subcode (0xxx); accepts: 1000–9999
'^[^1-9]%d%d%d$', -- 4 digits without subcode (0xxx); accepts: 1000–9999
'^%d%d%d%d%d%d+', -- 6 or more digits
'^%d%d?%d?$', -- less than 4 digits without subcode (with subcode is legitimate)
'^5555$', -- test registrant will never resolve
'[^%d%.]', -- any character that isn't a digit or a dot
}
if not ignore_invalid then
if registrant then -- when DOI has proper form
for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns
if registrant:match (pattern) then -- to validate registrant codes
err_flag = set_message ('err_bad_doi'); -- when found, mark this DOI as bad
break; -- and done
end
end
else
err_flag = set_message ('err_bad_doi'); -- invalid directory or malformed
end
else
set_message ('maint_doi_ignore');
end
if err_flag then
options.coins_list_t['DOI'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access,
auto_link = not (err_flag or is_set (inactive) or ignore_invalid) and 'doi' or nil -- do not auto-link when |doi-broken-date= has a value or when there is a DOI error or (to play it safe, after all, auto-linking is not essential) when invalid DOIs are ignored
}) .. (inactive or '');
return text;
end
--[[--------------------------< H D L >------------------------------------------------------------------------
Formats an HDL with minor error checking.
HDL names contain two parts: prefix and suffix separated by a forward slash.
Prefix: character string using any character in the UCS-2 character set except '/'
Suffix: character string of any length using any character in the UCS-2 character set chosen by the registrant
This function checks a HDL name for: prefix/suffix. If the HDL name contains spaces, endashes, or, if it ends
with a period or a comma, this function will emit a bad_hdl error message.
HDL names are case-insensitive and can incorporate any printable Unicode characters so the test for endashes and
terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely
if ever used in HDLs.
Query string parameters are named here: http://www.handle.net/proxy_servlet.html. query strings are not displayed
but since '?' is an allowed character in an HDL, '?' followed by one of the query parameters is the only way we
have to detect the query string so that it isn't URL-encoded with the rest of the identifier.
]]
local function hdl (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local query_params = { -- list of known query parameters from http://www.handle.net/proxy_servlet.html
'noredirect',
'ignore_aliases',
'auth',
'cert',
'index',
'type',
'urlappend',
'locatt',
'action',
}
local hdl, suffix, param = id:match ('(.-)(%?(%a+).+)$'); -- look for query string
local found;
if hdl then -- when there are query strings, this is the handle identifier portion
for _, q in ipairs (query_params) do -- spin through the list of query parameters
if param:match ('^' .. q) then -- if the query string begins with one of the parameters
found = true; -- announce a find
break; -- and stop looking
end
end
end
if found then
id = hdl; -- found so replace id with the handle portion; this will be URL-encoded, suffix will not
else
suffix = ''; -- make sure suffix is empty string for concatenation else
end
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, suffix = suffix, separator = handler.separator, encode = handler.encode, access = access})
if nil == id:match("^[^%s–]-/[^%s–]-[^%.,]$") then -- HDL must contain a forward slash, must not contain spaces, endashes, and must not end with period or comma
set_message ('err_bad_hdl' );
options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< I S B N >----------------------------------------------------------------------
Determines whether an ISBN string is valid
]]
local function isbn (options)
local isbn_str = options.id;
local ignore_invalid = options.accept;
local handler = options.handler;
local function return_result (check, err_type) -- local function to handle the various returns
local ISBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect,
prefix = handler.prefix, id = isbn_str, separator = handler.separator});
if ignore_invalid then -- if ignoring ISBN errors
set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error
else -- here when not ignoring
if not check then -- and there is an error
options.coins_list_t['ISBN'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_isbn', err_type); -- set an error message
return ISBN; -- return id text
end
end
return ISBN; -- return id text
end
if nil ~= isbn_str:match ('[^%s-0-9X]') then
return return_result (false, cfg.err_msg_supl.char); -- fail if isbn_str contains anything but digits, hyphens, or the uppercase X
end
local id = isbn_str:gsub ('[%s-]', ''); -- remove hyphens and whitespace
local len = id:len();
if len ~= 10 and len ~= 13 then
return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length
end
if len == 10 then
if id:match ('^%d*X?$') == nil then -- fail if isbn_str has 'X' anywhere but last position
return return_result (false, cfg.err_msg_supl.form);
end
if not is_valid_isxn (id, 10) then -- test isbn-10 for numerical validity
return return_result (false, cfg.err_msg_supl.check); -- fail if isbn-10 is not numerically valid
end
if id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin)
return return_result (false, cfg.err_msg_supl.group); -- fail if isbn-10 begins with 630/1
end
return return_result (true, cfg.err_msg_supl.check); -- pass if isbn-10 is numerically valid
else
if id:match ('^%d+$') == nil then
return return_result (false, cfg.err_msg_supl.char); -- fail if ISBN-13 is not all digits
end
if id:match ('^97[89]%d*$') == nil then
return return_result (false, cfg.err_msg_supl.prefix); -- fail when ISBN-13 does not begin with 978 or 979
end
if id:match ('^9790') then
return return_result (false, cfg.err_msg_supl.group); -- group identifier '0' is reserved to ISMN
end
return return_result (is_valid_isxn_13 (id), cfg.err_msg_supl.check);
end
end
--[[--------------------------< A S I N >----------------------------------------------------------------------
Formats a link to Amazon. Do simple error checking: ASIN must be mix of 10 numeric or uppercase alpha
characters. If a mix, first character must be uppercase alpha; if all numeric, ASINs must be 10-digit
ISBN. If 10-digit ISBN, add a maintenance category so a bot or AWB script can replace |asin= with |isbn=.
Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit.
|asin=630....... and |asin=631....... are (apparently) not a legitimate ISBN though it checksums as one; these
do not cause this function to emit the maint_asin message
This function is positioned here because it calls isbn()
]]
local function asin (options)
local id = options.id;
local domain = options.ASINTLD;
local err_flag;
if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then
err_flag = set_message ('err_bad_asin'); -- ASIN is not a mix of 10 uppercase alpha and numeric characters
else
if id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X)
if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10
if not id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not a valid isbn prefixes but are used by amazon as a numeric identifier
err_flag = set_message ('err_bad_asin'); -- ASIN has ISBN-10 form but begins with something other than 630/1 so probably an isbn
end
elseif not is_set (err_flag) then
err_flag = set_message ('err_bad_asin'); -- ASIN is not ISBN-10
end
elseif not id:match("^%u[%d%u]+$") then
err_flag = set_message ('err_bad_asin'); -- asin doesn't begin with uppercase alpha
end
end
if (not is_set (domain)) or in_array (domain, {'us'}) then -- default: United States
domain = "com";
elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom
domain = "co." .. domain;
elseif in_array (domain, {'z.cn'}) then -- China
domain = "cn";
elseif in_array (domain, {'au', 'br', 'mx', 'sg', 'tr'}) then -- Australia, Brazil, Mexico, Singapore, Turkey
domain = "com." .. domain;
elseif not in_array (domain, {'ae', 'ca', 'cn', 'de', 'es', 'fr', 'in', 'it', 'nl', 'pl', 'sa', 'se', 'co.jp', 'co.uk', 'com', 'com.au', 'com.br', 'com.mx', 'com.sg', 'com.tr'}) then -- Arabic Emirates, Canada, China, Germany, Spain, France, Indonesia, Italy, Netherlands, Poland, Saudi Arabia, Sweden (as of 2021-03 Austria (.at), Liechtenstein (.li) and Switzerland (.ch) still redirect to the German site (.de) with special settings, so don't maintain local ASINs for them)
err_flag = set_message ('err_bad_asin_tld'); -- unsupported asin-tld value
end
local handler = options.handler;
if not is_set (err_flag) then
options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; -- asin for coins
else
options.coins_list_t['ASIN'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix .. domain .. "/dp/",
id = id, encode = handler.encode, separator = handler.separator})
end
--[[--------------------------< I S M N >----------------------------------------------------------------------
Determines whether an ISMN string is valid. Similar to ISBN-13, ISMN is 13 digits beginning 979-0-... and uses the
same check digit calculations. See http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf
section 2, pages 9–12.
ismn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx)
or an identifier registered at info-uri.info (info:)
]]
local function ismn (options)
local id = options.id;
local handler = options.handler;
local text;
local valid_ismn = true;
local id_copy;
id_copy = id; -- save a copy because this testing is destructive
id = id:gsub ('[%s-]', ''); -- remove hyphens and white space
if 13 ~= id:len() or id:match ("^9790%d*$" ) == nil then -- ISMN must be 13 digits and begin with 9790
valid_ismn = false;
else
valid_ismn=is_valid_isxn_13 (id); -- validate ISMN
end
-- text = internal_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- use this (or external version) when there is some place to link to
-- prefix = handler.prefix, id = id_copy, separator = handler.separator, encode = handler.encode})
text = table.concat ( -- because no place to link to yet
{
make_wikilink (link_label_make (handler), handler.label),
handler.separator,
id_copy
});
if false == valid_ismn then
options.coins_list_t['ISMN'] = nil; -- when error, unset so not included in COinS; not really necessary here because ismn not made part of COinS
set_message ('err_bad_ismn'); -- create an error message if the ISMN is invalid
end
return text;
end
--[[--------------------------< I S S N >----------------------------------------------------------------------
Validate and format an ISSN. This code fixes the case where an editor has included an ISSN in the citation but
has separated the two groups of four digits with a space. When that condition occurred, the resulting link looked
like this:
|issn=0819 4327 gives: [http://www.worldcat.org/issn/0819 4327 0819 4327] -- can't have spaces in an external link
This code now prevents that by inserting a hyphen at the ISSN midpoint. It also validates the ISSN for length
and makes sure that the checkdigit agrees with the calculated value. Incorrect length (8 digits), characters
other than 0-9 and X, or checkdigit / calculated value mismatch will all cause a check ISSN error message. The
ISSN is always displayed with a hyphen, even if the ISSN was given as a single group of 8 digits.
]]
local function issn (options)
local id = options.id;
local handler = options.handler;
local ignore_invalid = options.accept;
local issn_copy = id; -- save a copy of unadulterated ISSN; use this version for display if ISSN does not validate
local text;
local valid_issn = true;
id = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace
if 8 ~= id:len() or nil == id:match ("^%d*X?$" ) then -- validate the ISSN: 8 digits long, containing only 0-9 or X in the last position
valid_issn = false; -- wrong length or improper character
else
valid_issn = is_valid_isxn (id, 8); -- validate ISSN
end
if true == valid_issn then
id = string.sub (id, 1, 4 ) .. "-" .. string.sub (id, 5 ); -- if valid, display correctly formatted version
else
id = issn_copy; -- if not valid, show the invalid ISSN with error message
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
if ignore_invalid then
set_message ('maint_issn_ignore');
else
if false == valid_issn then
options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- create an error message if the ISSN is invalid
end
end
return text;
end
--[[--------------------------< J F M >-----------------------------------------------------------------------
A numerical identifier in the form nn.nnnn.nn
]]
local function jfm (options)
local id = options.id;
local handler = options.handler;
local id_num;
id_num = id:match ('^[Jj][Ff][Mm](.*)$'); -- identifier with jfm prefix; extract identifier
if is_set (id_num) then
set_message ('maint_jfm_format');
else -- plain number without JFM prefix
id_num = id; -- if here id does not have prefix
end
if id_num and id_num:match('^%d%d%.%d%d%d%d%.%d%d$') then
id = id_num; -- jfm matches pattern
else
set_message ('err_bad_jfm' ); -- set an error message
options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< J S T O R >--------------------------------------------------------------------
Format a JSTOR with some error checking
]]
local function jstor (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then
set_message ('err_bad_jstor'); -- set an error message
options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
end
--[[--------------------------< L C C N >----------------------------------------------------------------------
Format LCCN link and do simple error checking. LCCN is a character string 8-12 characters long. The length of
the LCCN dictates the character type of the first 1-3 characters; the rightmost eight are always digits.
http://info-uri.info/registry/OAIHandler?verb=GetRecord&metadataPrefix=reg&identifier=info:lccn/
length = 8 then all digits
length = 9 then lccn[1] is lowercase alpha
length = 10 then lccn[1] and lccn[2] are both lowercase alpha or both digits
length = 11 then lccn[1] is lower case alpha, lccn[2] and lccn[3] are both lowercase alpha or both digits
length = 12 then lccn[1] and lccn[2] are both lowercase alpha
]]
local function lccn (options)
local lccn = options.id;
local handler = options.handler;
local err_flag; -- presume that LCCN is valid
local id = lccn; -- local copy of the LCCN
id = normalize_lccn (id); -- get canonical form (no whitespace, hyphens, forward slashes)
local len = id:len(); -- get the length of the LCCN
if 8 == len then
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits)
err_flag = set_message ('err_bad_lccn'); -- set an error message
end
elseif 9 == len then -- LCCN should be adddddddd
if nil == id:match("%l%d%d%d%d%d%d%d%d") then -- does it match our pattern?
err_flag = set_message ('err_bad_lccn'); -- set an error message
end
elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ...
if nil == id:match("^%l%l%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
end
elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd
if not (id:match("^%l%l%l%d%d%d%d%d%d%d%d") or id:match("^%l%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
elseif 12 == len then -- LCCN should be aadddddddddd
if not id:match("^%l%l%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
else
err_flag = set_message ('err_bad_lccn'); -- wrong length, set an error message
end
if not is_set (err_flag) and nil ~= lccn:find ('%s') then
err_flag = set_message ('err_bad_lccn'); -- lccn contains a space, set an error message
end
if is_set (err_flag) then
options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = lccn, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< M R >--------------------------------------------------------------------------
A seven digit number; if not seven digits, zero-fill leading digits to make seven digits.
]]
local function mr (options)
local id = options.id;
local handler = options.handler;
local id_num;
local id_len;
id_num = id:match ('^[Mm][Rr](%d+)$'); -- identifier with mr prefix
if is_set (id_num) then
set_message ('maint_mr_format'); -- add maint cat
else -- plain number without mr prefix
id_num = id:match ('^%d+$'); -- if here id is all digits
end
id_len = id_num and id_num:len() or 0;
if (7 >= id_len) and (0 ~= id_len) then
id = string.rep ('0', 7-id_len) .. id_num; -- zero-fill leading digits
else
set_message ('err_bad_mr'); -- set an error message
options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< O C L C >----------------------------------------------------------------------
Validate and format an OCLC ID. https://www.oclc.org/batchload/controlnumber.en.html {{dead link}}
archived at: https://web.archive.org/web/20161228233804/https://www.oclc.org/batchload/controlnumber.en.html
]]
local function oclc (options)
local id = options.id;
local handler = options.handler;
local number;
if id:match('^ocm%d%d%d%d%d%d%d%d$') then -- ocm prefix and 8 digits; 001 field (12 characters)
number = id:match('ocm(%d+)'); -- get the number
elseif id:match('^ocn%d%d%d%d%d%d%d%d%d$') then -- ocn prefix and 9 digits; 001 field (12 characters)
number = id:match('ocn(%d+)'); -- get the number
elseif id:match('^on%d%d%d%d%d%d%d%d%d%d+$') then -- on prefix and 10 or more digits; 001 field (12 characters)
number = id:match('^on(%d%d%d%d%d%d%d%d%d%d+)$'); -- get the number
elseif id:match('^%(OCoLC%)[1-9]%d*$') then -- (OCoLC) prefix and variable number digits; no leading zeros; 035 field
number = id:match('%(OCoLC%)([1-9]%d*)'); -- get the number
if 9 < number:len() then
number = nil; -- constrain to 1 to 9 digits; change this when OCLC issues 10-digit numbers
end
elseif id:match('^%d+$') then -- no prefix
number = id; -- get the number
if 10 < number:len() then
number = nil; -- constrain to 1 to 10 digits; change this when OCLC issues 11-digit numbers
end
end
if number then -- proper format
id = number; -- exclude prefix, if any, from external link
else
set_message ('err_bad_oclc') -- add an error message if the id is malformed
options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< O P E N L I B R A R Y >--------------------------------------------------------
Formats an OpenLibrary link, and checks for associated errors.
]]
local function openlibrary (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local ident, code = id:gsub('^OL', ''):match("^(%d+([AMW]))$"); -- strip optional OL prefix followed immediately by digits followed by 'A', 'M', or 'W';
local err_flag;
local prefix = { -- these are appended to the handler.prefix according to code
['A']='authors/OL',
['M']='books/OL',
['W']='works/OL',
['X']='OL' -- not a code; spoof when 'code' in id is invalid
};
if not ident then
code = 'X'; -- no code or id completely invalid
ident = id; -- copy id to ident so that we display the flawed identifier
err_flag = set_message ('err_bad_ol');
end
if not is_set (err_flag) then
options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins
else
options.coins_list_t['OL'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix .. prefix[code],
id = ident, separator = handler.separator, encode = handler.encode,
access = access});
end
--[[--------------------------< O S T I >----------------------------------------------------------------------
Format OSTI and do simple error checking. OSTIs are sequential numbers beginning at 1 and counting up. This
code checks the OSTI to see that it contains only digits and is less than test_limit specified in the configuration;
the value in test_limit will need to be updated periodically as more OSTIs are issued.
NB. 1018 is the lowest OSTI number found in the wild (so far) and resolving OK on the OSTI site
]]
local function osti (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
if id:match("[^%d]") then -- if OSTI has anything but digits
set_message ('err_bad_osti'); -- set an error message
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
else -- OSTI is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries
set_message ('err_bad_osti'); -- set an error message
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
end
--[[--------------------------< P M C >------------------------------------------------------------------------
Format a PMC, do simple error checking, and check for embargoed articles.
The embargo parameter takes a date for a value. If the embargo date is in the future the PMC identifier will not
be linked to the article. If the embargo date is today or in the past, or if it is empty or omitted, then the
PMC identifier is linked to the article through the link at cfg.id_handlers['PMC'].prefix.
PMC embargo date testing is done in function is_embargoed () which is called earlier because when the citation
has |pmc=<value> but does not have a |url= then |title= is linked with the PMC link. Function is_embargoed ()
returns the embargo date if the PMC article is still embargoed, otherwise it returns an empty string.
PMCs are sequential numbers beginning at 1 and counting up. This code checks the PMC to see that it contains only digits and is less
than test_limit; the value in local variable test_limit will need to be updated periodically as more PMCs are issued.
]]
local function pmc (options)
local id = options.id;
local embargo = options.Embargo; -- TODO: lowercase?
local handler = options.handler;
local err_flag;
local id_num;
local text;
id_num = id:match ('^[Pp][Mm][Cc](%d+)$'); -- identifier with PMC prefix
if is_set (id_num) then
set_message ('maint_pmc_format');
else -- plain number without PMC prefix
id_num = id:match ('^%d+$'); -- if here id is all digits
end
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMC is outside test limit boundaries
err_flag = set_message ('err_bad_pmc'); -- set an error message
else
id = tostring (id_num); -- make sure id is a string
end
else -- when id format incorrect
err_flag = set_message ('err_bad_pmc'); -- set an error message
end
if is_set (embargo) and is_set (is_embargoed (embargo)) then -- is PMC is still embargoed?
text = table.concat ( -- still embargoed so no external link
{
make_wikilink (link_label_make (handler), handler.label),
handler.separator,
id,
});
else
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- no embargo date or embargo has expired, ok to link to article
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access,
auto_link = not err_flag and 'pmc' or nil -- do not auto-link when PMC has error
});
end
if err_flag then
options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< P M I D >----------------------------------------------------------------------
Format PMID and do simple error checking. PMIDs are sequential numbers beginning at 1 and counting up. This
code checks the PMID to see that it contains only digits and is less than test_limit; the value in local variable
test_limit will need to be updated periodically as more PMIDs are issued.
]]
local function pmid (options)
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if PMID has anything but digits
set_message ('err_bad_pmid'); -- set an error message
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
else -- PMID is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries
set_message ('err_bad_pmid'); -- set an error message
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< R F C >------------------------------------------------------------------------
Format RFC and do simple error checking. RFCs are sequential numbers beginning at 1 and counting up. This
code checks the RFC to see that it contains only digits and is less than test_limit specified in the configuration;
the value in test_limit will need to be updated periodically as more RFCs are issued.
An index of all RFCs is here: https://tools.ietf.org/rfc/
]]
local function rfc (options)
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if RFC has anything but digits
set_message ('err_bad_rfc'); -- set an error message
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
else -- RFC is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries
set_message ('err_bad_rfc'); -- set an error message
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access});
end
--[[--------------------------< S 2 C I D >--------------------------------------------------------------------
Format an S2CID, do simple error checking
S2CIDs are sequential numbers beginning at 1 and counting up. This code checks the S2CID to see that it is only
digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically
as more S2CIDs are issued.
]]
local function s2cid (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local id_num;
local text;
id_num = id:match ('^[1-9]%d*$'); -- id must be all digits; must not begin with 0; no open access flag
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries
set_message ('err_bad_s2cid'); -- set an error message
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
set_message ('err_bad_s2cid'); -- set an error message
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
return text;
end
--[[--------------------------< S B N >------------------------------------------------------------------------
9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits
sbn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx)
or an identifier registered at info-uri.info (info:)
]]
local function sbn (options)
local id = options.id;
local ignore_invalid = options.accept;
local handler = options.handler;
local function return_result (check, err_type) -- local function to handle the various returns
local SBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator});
if not ignore_invalid then -- if not ignoring SBN errors
if not check then
options.coins_list_t['SBN'] = nil; -- when error, unset so not included in COinS; not really necessary here because sbn not made part of COinS
set_message ('err_bad_sbn', {err_type}); -- display an error message
return SBN;
end
else
set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error (ToDo: Possibly switch to separate message for SBNs only)
end
return SBN;
end
if id:match ('[^%s-0-9X]') then
return return_result (false, cfg.err_msg_supl.char); -- fail if SBN contains anything but digits, hyphens, or the uppercase X
end
local ident = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace; they interfere with the rest of the tests
if 9 ~= ident:len() then
return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length
end
if ident:match ('^%d*X?$') == nil then
return return_result (false, cfg.err_msg_supl.form); -- fail if SBN has 'X' anywhere but last position
end
return return_result (is_valid_isxn ('0' .. ident, 10), cfg.err_msg_supl.check);
end
--[[--------------------------< S S R N >----------------------------------------------------------------------
Format an SSRN, do simple error checking
SSRNs are sequential numbers beginning at 100? and counting up. This code checks the SSRN to see that it is
only digits and is greater than 99 and less than test_limit; the value in local variable test_limit will need
to be updated periodically as more SSRNs are issued.
]]
local function ssrn (options)
local id = options.id;
local handler = options.handler;
local id_num;
local text;
id_num = id:match ('^%d+$'); -- id must be all digits
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries
set_message ('err_bad_ssrn'); -- set an error message
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
set_message ('err_bad_ssrn'); -- set an error message
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = options.access});
return text;
end
--[[--------------------------< U S E N E T _ I D >------------------------------------------------------------
Validate and format a usenet message id. Simple error checking, looks for 'id-left@id-right' not enclosed in
'<' and/or '>' angle brackets.
]]
local function usenet_id (options)
local id = options.id;
local handler = options.handler;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>'
set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid
options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< Z B L >-----------------------------------------------------------------------
A numerical identifier in the form nnnn.nnnnn - leading zeros in the first quartet optional
format described here: http://emis.mi.sanu.ac.rs/ZMATH/zmath/en/help/search/
temporary format is apparently eight digits. Anything else is an error
]]
local function zbl (options)
local id = options.id;
local handler = options.handler;
if id:match('^%d%d%d%d%d%d%d%d$') then -- is this identifier using temporary format?
set_message ('maint_zbl'); -- yes, add maint cat
elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format?
set_message ('err_bad_zbl'); -- no, set an error message
options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--============================<< I N T E R F A C E F U N C T I O N S >>==========================================
--[[--------------------------< E X T R A C T _ I D S >------------------------------------------------------------
Populates ID table from arguments using configuration settings. Loops through cfg.id_handlers and searches args for
any of the parameters listed in each cfg.id_handlers['...'].parameters. If found, adds the parameter and value to
the identifier list. Emits redundant error message if more than one alias exists in args
]]
local function extract_ids (args)
local id_list = {}; -- list of identifiers found in args
for k, v in pairs (cfg.id_handlers) do -- k is uppercase identifier name as index to cfg.id_handlers; e.g. cfg.id_handlers['ISBN'], v is a table
v = select_one (args, v.parameters, 'err_redundant_parameters' ); -- v.parameters is a table of aliases for k; here we pick one from args if present
if is_set (v) then id_list[k] = v; end -- if found in args, add identifier to our list
end
return id_list;
end
--[[--------------------------< E X T R A C T _ I D _ A C C E S S _ L E V E L S >--------------------------------------
Fetches custom id access levels from arguments using configuration settings. Parameters which have a predefined access
level (e.g. arxiv) do not use this function as they are directly rendered as free without using an additional parameter.
returns a table of k/v pairs where k is same as the identifier's key in cfg.id_handlers and v is the assigned (valid) keyword
access-level values must match the case used in cfg.keywords_lists['id-access'] (lowercase unless there is some special reason for something else)
]]
local function extract_id_access_levels (args, id_list)
local id_accesses_list = {};
for k, v in pairs (cfg.id_handlers) do
local access_param = v.custom_access; -- name of identifier's access-level parameter
if is_set (access_param) then
local access_level = args[access_param]; -- get the assigned value if there is one
if is_set (access_level) then
if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required
set_message ('err_invalid_param_val', {access_param, access_level});
access_level = nil; -- invalid so unset
end
if not is_set (id_list[k]) then -- identifier access-level must have a matching identifier
set_message ('err_param_access_requires_param', {k:lower()}); -- parameter name is uppercase in cfg.id_handlers (k); lowercase for error message
end
id_accesses_list[k] = cfg.keywords_xlate[access_level]; -- get translated keyword
end
end
end
return id_accesses_list;
end
--[[--------------------------< B U I L D _ I D _ L I S T >----------------------------------------------------
render the identifiers into a sorted sequence table
<ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value
<options_t> is a table of various k/v option pairs provided in the call to new_build_id_list();
modified by this function and passed to all identifier rendering functions
<access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid)
returns a sequence table of sorted (by hkey - 'handler' key) rendered identifier strings
]]
local function build_id_list (ID_list_coins_t, options_t, access_levels_t)
local ID_list_t = {};
local accept;
local func_map = { --function map points to functions associated with hkey identifier
['ARXIV'] = arxiv,
['ASIN'] = asin,
['BIBCODE'] = bibcode,
['BIORXIV'] = biorxiv,
['CITESEERX'] = citeseerx,
['DOI'] = doi,
['EISSN'] = issn,
['HDL'] = hdl,
['ISBN'] = isbn,
['ISMN'] = ismn,
['ISSN'] = issn,
['JFM'] = jfm,
['JSTOR'] = jstor,
['LCCN'] = lccn,
['MR'] = mr,
['OCLC'] = oclc,
['OL'] = openlibrary,
['OSTI'] = osti,
['PMC'] = pmc,
['PMID'] = pmid,
['RFC'] = rfc,
['S2CID'] = s2cid,
['SBN'] = sbn,
['SSRN'] = ssrn,
['USENETID'] = usenet_id,
['ZBL'] = zbl,
}
for hkey, v in pairs (ID_list_coins_t) do
v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else
-- every function gets the options table with value v and accept boolean
options_t.hkey = hkey; -- ~/Configuration handler key
options_t.id = v; -- add that identifier value to the options table
options_t.accept = accept; -- add the accept boolean flag
options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter
options_t.handler = cfg.id_handlers[hkey];
options_t.coins_list_t = ID_list_coins_t; -- pointer to ID_list_coins_t; for |asin= and |ol=; also to keep erroneous values out of the citation's metadata
options_t.coins_list_t[hkey] = v; -- id value without accept-as-written markup for metadata
if options_t.handler.access and not in_array (options_t.handler.access, cfg.keywords_lists['id-access']) then
error (cfg.messages['unknown_ID_access'] .. options_t.handler.access); -- here when handler access key set to a value not listed in list of allowed id access keywords
end
if func_map[hkey] then
local id_text = func_map[hkey] (options_t); -- call the function to get identifier text and any error message
table.insert (ID_list_t, {hkey, id_text}); -- add identifier text to the output sequence table
else
error (cfg.messages['unknown_ID_key'] .. hkey); -- here when func_map doesn't have a function for hkey
end
end
local function comp (a, b) -- used by following table.sort()
return a[1]:lower() < b[1]:lower(); -- sort by hkey
end
table.sort (ID_list_t, comp); -- sequence table of tables sort
for k, v in ipairs (ID_list_t) do -- convert sequence table of tables to simple sequence table of strings
ID_list_t[k] = v[2]; -- v[2] is the identifier rendering from the call to the various functions in func_map{}
end
return ID_list_t;
end
--[[--------------------------< O P T I O N S _ C H E C K >----------------------------------------------------
check that certain option parameters have their associated identifier parameters with values
<ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value
<ID_support_t> is a sequence table of tables created in citation0() where each subtable has four elements:
[1] is the support parameter's assigned value; empty string if not set
[2] is a text string same as key in cfg.id_handlers
[3] is cfg.error_conditions key used to create error message
[4] is original ID support parameter name used to create error message
returns nothing; on error emits an appropriate error message
]]
local function options_check (ID_list_coins_t, ID_support_t)
for _, v in ipairs (ID_support_t) do
if is_set (v[1]) and not ID_list_coins_t[v[2]] then -- when support parameter has a value but matching identifier parameter is missing or empty
set_message (v[3], (v[4])); -- emit the appropriate error message
end
end
end
--[[--------------------------< I D E N T I F I E R _ L I S T S _ G E T >--------------------------------------
Creates two identifier lists: a k/v table of identifiers and their values to be used locally and for use in the
COinS metadata, and a sequence table of the rendered identifier strings that will be included in the rendered
citation.
]]
local function identifier_lists_get (args_t, options_t, ID_support_t)
local ID_list_coins_t = extract_ids (args_t); -- get a table of identifiers and their values for use locally and for use in COinS
options_check (ID_list_coins_t, ID_support_t); -- ID support parameters must have matching identifier parameters
local ID_access_levels_t = extract_id_access_levels (args_t, ID_list_coins_t); -- get a table of identifier access levels
local ID_list_t = build_id_list (ID_list_coins_t, options_t, ID_access_levels_t); -- get a sequence table of rendered identifier strings
return ID_list_t, ID_list_coins_t; -- return the tables
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from select Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
set_message = utilities_page_ptr.set_message;
select_one = utilities_page_ptr.select_one;
substitute = utilities_page_ptr.substitute;
make_wikilink = utilities_page_ptr.make_wikilink;
z = utilities_page_ptr.z; -- table of tables in Module:Citation/CS1/Utilities
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
auto_link_urls = auto_link_urls, -- table of identifier URLs to be used when auto-linking |title=
identifier_lists_get = identifier_lists_get, -- experiment to replace individual calls to build_id_list(), extract_ids, extract_id_access_levels
is_embargoed = is_embargoed;
set_selected_modules = set_selected_modules;
}
0f40bcba575710f5da9e7d29a8305288fbb30ac4
Module:Citation/CS1/Whitelist
828
52
119
2022-01-22T14:11:22Z
Canopus >Trappist the monk
0
update per [[Wikipedia:Village_pump_(proposals)#rfc:_shall_we_update_cs1/2?|RfC]];
Scribunto
text/plain
--[[--------------------------< S U P P O R T E D P A R A M E T E R S >--------------------------------------
Because a steady-state signal conveys no useful information, whitelist.basic_arguments[] list items can have three values:
true - these parameters are valid and supported parameters
false - these parameters are deprecated but still supported
tracked - these parameters are valid and supported parameters tracked in an eponymous properties category
nil - these parameters are no longer supported. remove entirely
]]
local basic_arguments = {
['accessdate'] = true,
['access-date'] = true,
['agency'] = true,
['archivedate'] = true,
['archive-date'] = true,
['archive-format'] = true,
['archiveurl'] = true,
['archive-url'] = true,
['article'] = true,
['article-format'] = true,
['article-url'] = true,
['article-url-access'] = true,
['arxiv'] = true, -- cite arxiv; here because allowed in cite ... as identifier
['asin'] = true,
['ASIN'] = true,
['asin-tld'] = true,
['at'] = true,
['author'] = true,
['author-first'] = true,
['author-given'] = true,
['author-last'] = true,
['author-surname'] = true,
['authorlink'] = true,
['author-link'] = true,
['author-mask'] = true,
['authors'] = true,
['bibcode'] = true,
['bibcode-access'] = true,
['biorxiv'] = true, -- cite biorxiv; here because allowed in cite ... as identifier
['chapter'] = true,
['chapter-format'] = true,
['chapter-url'] = true,
['chapter-url-access'] = true,
['citeseerx'] = true, -- cite citeseerx; here because allowed in cite ... as identifier
['collaboration'] = true,
['contribution'] = true,
['contribution-format'] = true,
['contribution-url'] = true,
['contribution-url-access'] = true,
['contributor'] = true,
['contributor-first'] = true,
['contributor-given'] = true,
['contributor-last'] = true,
['contributor-surname'] = true,
['contributor-link'] = true,
['contributor-mask'] = true,
['date'] = true,
['department'] = true,
['df'] = true,
['dictionary'] = true,
['display-authors'] = true,
['display-contributors'] = true,
['display-editors'] = true,
['display-interviewers'] = true,
['display-subjects'] = true,
['display-translators'] = true,
['doi'] = true,
['DOI'] = true,
['doi-access'] = true,
['doi-broken-date'] = true,
['edition'] = true,
['editor'] = true,
['editor-first'] = true,
['editor-given'] = true,
['editor-last'] = true,
['editor-surname'] = true,
['editor-link'] = true,
['editor-mask'] = true,
['eissn'] = true,
['EISSN'] = true,
['encyclopaedia'] = true,
['encyclopedia'] = true,
['entry'] = true,
['entry-format'] = true,
['entry-url'] = true,
['entry-url-access'] = true,
['eprint'] = true, -- cite arxiv; here because allowed in cite ... as identifier
['first'] = true,
['format'] = true,
['given'] = true,
['hdl'] = true,
['HDL'] = true,
['hdl-access'] = true,
['host'] = true, -- unique to certain templates?
['id'] = true,
['ID'] = true,
['institution'] = true, -- constrain to cite thesis?
['interviewer'] = true,
['interviewer-first'] = true,
['interviewer-given'] = true,
['interviewer-last'] = true,
['interviewer-surname'] = true,
['interviewer-link'] = true,
['interviewer-mask'] = true,
['isbn'] = true,
['ISBN'] = true,
['ismn'] = true,
['ISMN'] = true,
['issn'] = true,
['ISSN'] = true,
['issue'] = true,
['jfm'] = true,
['JFM'] = true,
['journal'] = true,
['jstor'] = true,
['JSTOR'] = true,
['jstor-access'] = true,
['lang'] = true,
['language'] = true,
['last'] = true,
['lay-date'] = false,
['lay-format'] = false,
['lay-source'] = false,
['lay-url'] = false,
['lccn'] = true,
['LCCN'] = true,
['location'] = true,
['magazine'] = true,
['medium'] = true,
['minutes'] = true, -- constrain to cite AV media and podcast?
['mode'] = true,
['mr'] = true,
['MR'] = true,
['name-list-style'] = true,
['newspaper'] = true,
['no-pp'] = true,
['no-tracking'] = true,
['number'] = true,
['oclc'] = true,
['OCLC'] = true,
['ol'] = true,
['OL'] = true,
['ol-access'] = true,
['orig-date'] = true,
['origyear'] = true,
['orig-year'] = true,
['osti'] = true,
['OSTI'] = true,
['osti-access'] = true,
['others'] = true,
['p'] = true,
['page'] = true,
['pages'] = true,
['people'] = true,
['periodical'] = true,
['place'] = true,
['pmc'] = true,
['PMC'] = true,
['pmc-embargo-date'] = true,
['pmid'] = true,
['PMID'] = true,
['postscript'] = true,
['pp'] = true,
['publication-date'] = true,
['publication-place'] = true,
['publisher'] = true,
['quotation'] = true,
['quote'] = true,
['quote-page'] = true,
['quote-pages'] = true,
['ref'] = true,
['rfc'] = true,
['RFC'] = true,
['sbn'] = true,
['SBN'] = true,
['scale'] = true,
['script-article'] = true,
['script-chapter'] = true,
['script-contribution'] = true,
['script-entry'] = true,
['script-journal'] = true,
['script-magazine'] = true,
['script-newspaper'] = true,
['script-periodical'] = true,
['script-quote'] = true,
['script-section'] = true,
['script-title'] = true,
['script-website'] = true,
['script-work'] = true,
['section'] = true,
['section-format'] = true,
['section-url'] = true,
['section-url-access'] = true,
['series'] = true,
['ssrn'] = true, -- cite ssrn; these three here because allowed in cite ... as identifier
['SSRN'] = true,
['ssrn-access'] = true,
['subject'] = true,
['subject-link'] = true,
['subject-mask'] = true,
['surname'] = true,
['s2cid'] = true,
['S2CID'] = true,
['s2cid-access'] = true,
['template-doc-demo'] = true,
['time'] = true, -- constrain to cite av media and podcast?
['time-caption'] = true, -- constrain to cite av media and podcast?
['title'] = true,
['title-link'] = true,
['translator'] = true,
['translator-first'] = true,
['translator-given'] = true,
['translator-last'] = true,
['translator-surname'] = true,
['translator-link'] = true,
['translator-mask'] = true,
['trans-article'] = true,
['trans-chapter'] = true,
['trans-contribution'] = true,
['trans-entry'] = true,
['trans-journal'] = true,
['trans-magazine'] = true,
['trans-newspaper'] = true,
['trans-periodical'] = true,
['trans-quote'] = true,
['trans-section'] = true,
['trans-title'] = true,
['trans-website'] = true,
['trans-work'] = true,
['type'] = true,
['url'] = true,
['URL'] = true,
['url-access'] = true,
['url-status'] = true,
['vauthors'] = true,
['veditors'] = true,
['version'] = true,
['via'] = true,
['volume'] = true,
['website'] = true,
['work'] = true,
['year'] = true,
['zbl'] = true,
['ZBL'] = true,
}
local numbered_arguments = {
['author#'] = true,
['author-first#'] = true,
['author#-first'] = true,
['author-given#'] = true,
['author#-given'] = true,
['author-last#'] = true,
['author#-last'] = true,
['author-surname#'] = true,
['author#-surname'] = true,
['author-link#'] = true,
['author#-link'] = true,
['authorlink#'] = true,
['author#link'] = true,
['author-mask#'] = true,
['author#-mask'] = true,
['contributor#'] = true,
['contributor-first#'] = true,
['contributor#-first'] = true,
['contributor-given#'] = true,
['contributor#-given'] = true,
['contributor-last#'] = true,
['contributor#-last'] = true,
['contributor-surname#'] = true,
['contributor#-surname'] = true,
['contributor-link#'] = true,
['contributor#-link'] = true,
['contributor-mask#'] = true,
['contributor#-mask'] = true,
['editor#'] = true,
['editor-first#'] = true,
['editor#-first'] = true,
['editor-given#'] = true,
['editor#-given'] = true,
['editor-last#'] = true,
['editor#-last'] = true,
['editor-surname#'] = true,
['editor#-surname'] = true,
['editor-link#'] = true,
['editor#-link'] = true,
['editor-mask#'] = true,
['editor#-mask'] = true,
['first#'] = true,
['given#'] = true,
['host#'] = true,
['interviewer#'] = true,
['interviewer-first#'] = true,
['interviewer#-first'] = true,
['interviewer-given#'] = true,
['interviewer#-given'] = true,
['interviewer-last#'] = true,
['interviewer#-last'] = true,
['interviewer-surname#'] = true,
['interviewer#-surname'] = true,
['interviewer-link#'] = true,
['interviewer#-link'] = true,
['interviewer-mask#'] = true,
['interviewer#-mask'] = true,
['last#'] = true,
['subject#'] = true,
['subject-link#'] = true,
['subject#-link'] = true,
['subject-mask#'] = true,
['subject#-mask'] = true,
['surname#'] = true,
['translator#'] = true,
['translator-first#'] = true,
['translator#-first'] = true,
['translator-given#'] = true,
['translator#-given'] = true,
['translator-last#'] = true,
['translator#-last'] = true,
['translator-surname#'] = true,
['translator#-surname'] = true,
['translator-link#'] = true,
['translator#-link'] = true,
['translator-mask#'] = true,
['translator#-mask'] = true,
}
--[[--------------------------< P R E P R I N T S U P P O R T E D P A R A M E T E R S >--------------------
Cite arXiv, cite biorxiv, cite citeseerx, and cite ssrn are preprint templates that use the limited set of parameters
defined in the limited_basic_arguments and limited_numbered_arguments tables. Those lists are supplemented with a
template-specific list of parameters that are required by the particular template and may be exclusive to one of the
preprint templates. Some of these parameters may also be available to the general cs1|2 templates.
Same conventions for true/false/tracked/nil as above.
]]
local preprint_arguments = {
arxiv = {
['arxiv'] = true, -- cite arxiv and arxiv identifiers
['class'] = true,
['eprint'] = true, -- cite arxiv and arxiv identifiers
},
biorxiv = {
['biorxiv'] = true,
},
citeseerx = {
['citeseerx'] = true,
},
ssrn = {
['ssrn'] = true,
['SSRN'] = true,
['ssrn-access'] = true,
},
}
--[[--------------------------< L I M I T E D S U P P O R T E D P A R A M E T E R S >----------------------
cite arxiv, cite biorxiv, cite citeseerx, and cite ssrn templates are preprint templates so are allowed only a
limited subset of parameters allowed to all other cs1|2 templates. The limited subset is defined here.
Same conventions for true/false/tracked/nil as above.
]]
local limited_basic_arguments = {
['at'] = true,
['author'] = true,
['author-first'] = true,
['author-given'] = true,
['author-last'] = true,
['author-surname'] = true,
['author-link'] = true,
['authorlink'] = true,
['author-mask'] = true,
['authors'] = true,
['collaboration'] = true,
['date'] = true,
['df'] = true,
['display-authors'] = true,
['first'] = true,
['given'] = true,
['language'] = true,
['last'] = true,
['mode'] = true,
['name-list-style'] = true,
['no-tracking'] = true,
['p'] = true,
['page'] = true,
['pages'] = true,
['postscript'] = true,
['pp'] = true,
['quotation'] = true,
['quote'] = true,
['ref'] = true,
['surname'] = true,
['template-doc-demo'] = true,
['title'] = true,
['trans-title'] = true,
['vauthors'] = true,
['year'] = true,
}
local limited_numbered_arguments = {
['author#'] = true,
['author-first#'] = true,
['author#-first'] = true,
['author-given#'] = true,
['author#-given'] = true,
['author-last#'] = true,
['author#-last'] = true,
['author-surname#'] = true,
['author#-surname'] = true,
['author-link#'] = true,
['author#-link'] = true,
['authorlink#'] = true,
['author#link'] = true,
['author-mask#'] = true,
['author#-mask'] = true,
['first#'] = true,
['given#'] = true,
['last#'] = true,
['surname#'] = true,
}
--[[--------------------------< U N I Q U E _ A R G U M E N T S >----------------------------------------------
Some templates have unique parameters. Those templates and their unique parameters are listed here. Keys in this
table are the template's CitationClass parameter value
Same conventions for true/false/tracked/nil as above.
]]
local unique_arguments = {
['audio-visual'] = {
['transcript'] = true,
['transcript-format'] = true,
['transcript-url'] = true,
},
conference = {
['book-title'] = true,
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['event'] = true,
},
episode = {
['airdate'] = true,
['air-date'] = true,
['credits'] = true,
['episode-link'] = true, -- alias of |title-link=
['network'] = true,
['season'] = true,
['series-link'] = true,
['series-no'] = true,
['series-number'] = true,
['station'] = true,
['transcript'] = true,
['transcript-format'] = true,
['transcripturl'] = false,
['transcript-url'] = true,
},
mailinglist = {
['mailing-list'] = true,
},
map = {
['cartography'] = true,
['inset'] = true,
['map'] = true,
['map-format'] = true,
['map-url'] = true,
['map-url-access'] = true,
['script-map'] = true,
['sections'] = true,
['sheet'] = true,
['sheets'] = true,
['trans-map'] = true,
},
newsgroup = {
['message-id'] = true,
['newsgroup'] = true,
},
report = {
['docket'] = true,
},
serial = {
['airdate'] = true,
['air-date'] = true,
['credits'] = true,
['episode'] = true, -- cite serial only TODO: make available to cite episode?
['episode-link'] = true, -- alias of |title-link=
['network'] = true,
['series-link'] = true,
['station'] = true,
},
speech = {
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['event'] = true,
},
thesis = {
['degree'] = true,
['docket'] = true,
},
}
--[[--------------------------< T E M P L A T E _ L I S T _ G E T >--------------------------------------------
gets a list of the templates from table t
]]
local function template_list_get (t)
local out = {}; -- a table for output
for k, _ in pairs (t) do -- spin through the table and collect the keys
table.insert (out, k) -- add each key to the output table
end
return out; -- and done
end
--[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------
]]
return {
basic_arguments = basic_arguments,
numbered_arguments = numbered_arguments,
limited_basic_arguments = limited_basic_arguments,
limited_numbered_arguments = limited_numbered_arguments,
preprint_arguments = preprint_arguments,
preprint_template_list = template_list_get (preprint_arguments), -- make a template list from preprint_arguments{} table
unique_arguments = unique_arguments,
unique_param_template_list = template_list_get (unique_arguments), -- make a template list from unique_arguments{} table
};
6773846564c816e7f9eae451b65436cbda849bc5
Module:TableTools
828
73
161
2022-01-31T13:08:18Z
Canopus >MSGJ
0
updates/fixes requested by [[User:Uzume]]
Scribunto
text/plain
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should not --
-- be called directly from #invoke. --
------------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
function p.isPositiveInteger(v)
return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity
end
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false if
-- not. Although it doesn't operate on tables, it is included here as it is useful
-- for determining whether a value can be a valid table key. Lua will generate an
-- error if a NaN is used as a table key.
------------------------------------------------------------------------------------
function p.isNan(v)
return type(v) == 'number' and v ~= v
end
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
function p.shallowClone(t)
checkType('shallowClone', 1, t, 'table')
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
function p.removeDuplicates(arr)
checkType('removeDuplicates', 1, arr, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for _, v in ipairs(arr) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will return
-- {1, 3, 6}.
------------------------------------------------------------------------------------
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
return s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like {"foo1", "bar1", "foo2", "baz2"}, returns a table
-- of subtables in the format
-- {[1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'}}.
-- Keys that don't end with an integer are stored in a subtable named "other". The
-- compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for _ in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
elseif type1 == 'table' or type1 == 'boolean' or type1 == 'function' then
return tostring(item1) < tostring(item2)
else
return item1 < item2
end
end
------------------------------------------------------------------------------------
-- keysToList
--
-- Returns an array of the keys in a table, sorted using either a default
-- comparison function or a custom keySort function.
------------------------------------------------------------------------------------
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, {'function', 'boolean', 'nil'})
end
local arr = {}
local index = 1
for k in pairs(t) do
arr[index] = k
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(arr, keySort)
end
return arr
end
------------------------------------------------------------------------------------
-- sortedPairs
--
-- Iterates through a table, with the keys sorted using the keysToList function.
-- If there are only numerical keys, sparseIpairs is probably more efficient.
------------------------------------------------------------------------------------
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local arr = p.keysToList(t, keySort, true)
local i = 0
return function ()
i = i + 1
local key = arr[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- isArray
--
-- Returns true if the given value is a table and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArray(v)
if type(v) ~= 'table' then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- isArrayLike
--
-- Returns true if the given value is iterable and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArrayLike(v)
if not pcall(pairs, v) then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- invert
--
-- Transposes the keys and values in an array. For example, {"a", "b", "c"} ->
-- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to
-- the index of the last duplicate) and NaN values are ignored.
------------------------------------------------------------------------------------
function p.invert(arr)
checkType("invert", 1, arr, "table")
local isNan = p.isNan
local map = {}
for i, v in ipairs(arr) do
if not isNan(v) then
map[v] = i
end
end
return map
end
------------------------------------------------------------------------------------
-- listToSet
--
-- Creates a set from the array part of the table. Indexing the set by any of the
-- values of the array returns true. For example, {"a", "b", "c"} ->
-- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them
-- never equal to any value (including other NaNs or even themselves).
------------------------------------------------------------------------------------
function p.listToSet(arr)
checkType("listToSet", 1, arr, "table")
local isNan = p.isNan
local set = {}
for _, v in ipairs(arr) do
if not isNan(v) then
set[v] = true
end
end
return set
end
------------------------------------------------------------------------------------
-- deepCopy
--
-- Recursive deep copy function. Preserves identities of subtables.
------------------------------------------------------------------------------------
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = _deepCopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
------------------------------------------------------------------------------------
-- sparseConcat
--
-- Concatenates all values in the table that are indexed by a number, in order.
-- sparseConcat{a, nil, c, d} => "acd"
-- sparseConcat{nil, b, c, d} => "bcd"
------------------------------------------------------------------------------------
function p.sparseConcat(t, sep, i, j)
local arr = {}
local arr_i = 0
for _, v in p.sparseIpairs(t) do
arr_i = arr_i + 1
arr[arr_i] = v
end
return table.concat(arr, sep, i, j)
end
------------------------------------------------------------------------------------
-- length
--
-- Finds the length of an array, or of a quasi-array with keys such as "data1",
-- "data2", etc., using an exponential search algorithm. It is similar to the
-- operator #, but may return a different value when there are gaps in the array
-- portion of the table. Intended to be used on data loaded with mw.loadData. For
-- other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of the number
-- of unnamed template parameters, so use this function for frame.args.
------------------------------------------------------------------------------------
function p.length(t, prefix)
-- requiring module inline so that [[Module:Exponential search]] which is
-- only needed by this one function doesn't get millions of transclusions
local expSearch = require("Module:Exponential search")
checkType('length', 1, t, 'table')
checkType('length', 2, prefix, 'string', true)
return expSearch(function (i)
local key
if prefix then
key = prefix .. tostring(i)
else
key = i
end
return t[key] ~= nil
end) or 0
end
------------------------------------------------------------------------------------
-- inArray
--
-- Returns true if valueToFind is a member of the array, and false otherwise.
------------------------------------------------------------------------------------
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
085e7094ac84eb0132ee65822cf3f69cd8ba3d81
Template:Short description/lowercasecheck
10
67
149
2022-02-12T16:35:05Z
Canopus >ToBeFree
0
Changed protection settings for "[[Template:Short description/lowercasecheck]]": 4 million transclusions, through [[Template:Short description]] ([[WP:HRT]]) ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
{{#ifeq:<!--test first character for lower-case letter-->{{#invoke:string|find|1={{{1|}}}|2=^%l|plain=false}}|1
|<!-- first character is a lower case letter; test against whitelist
-->{{#switch: {{First word|{{{1|}}}}}<!--begin whitelist-->
|c. <!--for circa-->
|gTLD
|iMac
|iOS
|iOS,
|iPad
|iPhone
|iTunes
|macOS
|none
|pH
|pH-dependent=<!-- end whitelist; short description starts with an allowed lower-case string; whitelist matched; do nothing -->
|#default=<!-- apply category to track lower-case short descriptions -->{{main other|[[Category:Pages with lower-case short description|{{trim|{{{1|}}}}}]]}}{{Testcases other|{{red|CATEGORY APPLIED}}}}<!-- end whitelist test -->}}
|<!-- short description does not start with lower-case letter; do nothing; end lower-case test -->
}}<noinclude>
{{documentation}}
</noinclude>
9a6d4db14b74614625fd234b4f8ee3c8e1a235c0
Module:Convert
828
46
107
2022-02-13T04:01:13Z
Canopus >Johnuniq
0
update from sandbox per [[Template talk:Convert#Module version 27]]
Scribunto
text/plain
-- Convert a value from one unit of measurement to another.
-- Example: {{convert|123|lb|kg}} --> 123 pounds (56 kg)
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92)
local abs = math.abs
local floor = math.floor
local format = string.format
local log10 = math.log10
local ustring = mw.ustring
local ulen = ustring.len
local usub = ustring.sub
-- Configuration options to keep magic values in one location.
-- Conversion data and message text are defined in separate modules.
local config, maxsigfig
local numdot -- must be '.' or ',' or a character which works in a regex
local numsep, numsep_remove, numsep_remove2
local data_code, all_units
local text_code
local varname -- can be a code to use variable names that depend on value
local from_en_table -- to translate an output string of en digits to local language
local to_en_table -- to translate an input string of digits in local language to en
-- Use translation_table in convert/text to change the following.
local en_default -- true uses lang=en unless convert has lang=local or local digits
local group_method = 3 -- code for how many digits are in a group
local per_word = 'per' -- for units like "liters per kilometer"
local plural_suffix = 's' -- only other useful value is probably '' to disable plural unit names
local omitsep -- true to omit separator before local symbol/name
-- All units should be defined in the data module. However, to cater for quick changes
-- and experiments, any unknown unit is looked up in an extra data module, if it exists.
-- That module would be transcluded in only a small number of pages, so there should be
-- little server overhead from making changes, and changes should propagate quickly.
local extra_module -- name of module with extra units
local extra_units -- nil or table of extra units from extra_module
-- Some options in the invoking template can set variables used later in the module.
local currency_text -- for a user-defined currency symbol: {{convert|12|$/ha|$=€}} (euro replaces dollar)
local function from_en(text)
-- Input is a string representing a number in en digits with '.' decimal mark,
-- without digit grouping (which is done just after calling this).
-- Return the translation of the string with numdot and digits in local language.
if numdot ~= '.' then
text = text:gsub('%.', numdot)
end
if from_en_table then
text = text:gsub('%d', from_en_table)
end
return text
end
local function to_en(text)
-- Input is a string representing a number in the local language with
-- an optional numdot decimal mark and numsep digit grouping.
-- Return the translation of the string with '.' mark and en digits,
-- and no separators (they have to be removed here to handle cases like
-- numsep = '.' and numdot = ',' with input "1.234.567,8").
if to_en_table then
text = ustring.gsub(text, '%d', to_en_table)
end
if numsep_remove then
text = text:gsub(numsep_remove, '')
end
if numsep_remove2 then
text = text:gsub(numsep_remove2, '')
end
if numdot ~= '.' then
text = text:gsub(numdot, '.')
end
return text
end
local function decimal_mark(text)
-- Return ',' if text probably is using comma for decimal mark, or has no decimal mark.
-- Return '.' if text probably is using dot for decimal mark.
-- Otherwise return nothing (decimal mark not known).
if not text:find('[.,]') then return ',' end
text = text:gsub('^%-', ''):gsub('%+%d+/%d+$', ''):gsub('[Ee]%-?%d+$', '')
local decimal =
text:match('^0?([.,])%d+$') or
text:match('%d([.,])%d?%d?$') or
text:match('%d([.,])%d%d%d%d+$')
if decimal then return decimal end
if text:match('%.%d+%.') then return ',' end
if text:match('%,%d+,') then return '.' end
end
local add_warning, with_separator -- forward declarations
local function to_en_with_check(text, parms)
-- Version of to_en() for a wiki using numdot = ',' and numsep = '.' to check
-- text (an input number as a string) which might have been copied from enwiki.
-- For example, in '1.234' the '.' could be a decimal mark or a group separator.
-- From viwiki.
if to_en_table then
text = ustring.gsub(text, '%d', to_en_table)
end
if decimal_mark(text) == '.' then
local original = text
text = text:gsub(',', '') -- for example, interpret "1,234.5" as an enwiki value
if parms then
add_warning(parms, 0, 'cvt_enwiki_num', original, with_separator({}, text))
end
else
if numsep_remove then
text = text:gsub(numsep_remove, '')
end
if numsep_remove2 then
text = text:gsub(numsep_remove2, '')
end
if numdot ~= '.' then
text = text:gsub(numdot, '.')
end
end
return text
end
local function omit_separator(id)
-- Return true if there should be no separator before id (a unit symbol or name).
-- For zhwiki, there should be no separator if id uses local characters.
-- The following kludge should be a sufficient test.
if omitsep then
if id:sub(1, 2) == '-{' then -- for "-{...}-" content language variant
return true
end
if id:byte() > 127 then
local first = usub(id, 1, 1)
if first ~= 'Å' and first ~= '°' and first ~= 'µ' then
return true
end
end
end
return id:sub(1, 1) == '/' -- no separator before units like "/ha"
end
local spell_module -- name of module that can spell numbers
local speller -- function from that module to handle spelling (set if needed)
local wikidata_module, wikidata_data_module -- names of Wikidata modules
local wikidata_code, wikidata_data -- exported tables from those modules (set if needed)
local function set_config(args)
-- Set configuration options from template #invoke or defaults.
config = args
maxsigfig = config.maxsigfig or 14 -- maximum number of significant figures
local data_module, text_module
local sandbox = config.sandbox and ('/' .. config.sandbox) or ''
data_module = "Module:Convert/data" .. sandbox
text_module = "Module:Convert/text" .. sandbox
extra_module = "Module:Convert/extra" .. sandbox
wikidata_module = "Module:Convert/wikidata" .. sandbox
wikidata_data_module = "Module:Convert/wikidata/data" .. sandbox
spell_module = "Module:ConvertNumeric"
data_code = mw.loadData(data_module)
text_code = mw.loadData(text_module)
all_units = data_code.all_units
local translation = text_code.translation_table
if translation then
numdot = translation.numdot
numsep = translation.numsep
if numdot == ',' and numsep == '.' then
if text_code.all_messages.cvt_enwiki_num then
to_en = to_en_with_check
end
end
if translation.group then
group_method = translation.group
end
if translation.per_word then
per_word = translation.per_word
end
if translation.plural_suffix then
plural_suffix = translation.plural_suffix
end
varname = translation.varname
from_en_table = translation.from_en
local use_workaround = true
if use_workaround then
-- 2013-07-05 workaround bug by making a copy of the required table.
-- mw.ustring.gsub fails with a table (to_en_table) as the replacement,
-- if the table is accessed via mw.loadData.
local source = translation.to_en
if source then
to_en_table = {}
for k, v in pairs(source) do
to_en_table[k] = v
end
end
else
to_en_table = translation.to_en
end
if translation.lang == 'en default' then
en_default = true -- for hiwiki
end
omitsep = translation.omitsep -- for zhwiki
end
numdot = config.numdot or numdot or '.' -- decimal mark before fractional digits
numsep = config.numsep or numsep or ',' -- group separator for numbers
-- numsep should be ',' or '.' or '' or ' ' or a Unicode character.
-- numsep_remove must work in a regex to identify separators to be removed.
if numsep ~= '' then
numsep_remove = (numsep == '.') and '%.' or numsep
end
if numsep ~= ',' and numdot ~= ',' then
numsep_remove2 = ',' -- so numbers copied from enwiki will work
end
end
local function collection()
-- Return a table to hold items.
return {
n = 0,
add = function (self, item)
self.n = self.n + 1
self[self.n] = item
end,
}
end
local function divide(numerator, denominator)
-- Return integers quotient, remainder resulting from dividing the two
-- given numbers, which should be unsigned integers.
local quotient, remainder = floor(numerator / denominator), numerator % denominator
if not (0 <= remainder and remainder < denominator) then
-- Floating point limits may need this, as in {{convert|160.02|Ym|ydftin}}.
remainder = 0
end
return quotient, remainder
end
local function split(text, delimiter)
-- Return a numbered table with fields from splitting text.
-- The delimiter is used in a regex without escaping (for example, '.' would fail).
-- Each field has any leading/trailing whitespace removed.
local t = {}
text = text .. delimiter -- to get last item
for item in text:gmatch('%s*(.-)%s*' .. delimiter) do
table.insert(t, item)
end
return t
end
local function strip(text)
-- If text is a string, return its content with no leading/trailing
-- whitespace. Otherwise return nil (a nil argument gives a nil result).
if type(text) == 'string' then
return text:match("^%s*(.-)%s*$")
end
end
local function table_len(t)
-- Return length (<100) of a numbered table to replace #t which is
-- documented to not work if t is accessed via mw.loadData().
for i = 1, 100 do
if t[i] == nil then
return i - 1
end
end
end
local function wanted_category(catkey, catsort, want_warning)
-- Return message category if it is wanted in current namespace,
-- otherwise return ''.
local cat
local title = mw.title.getCurrentTitle()
if title then
local nsdefault = '0' -- default namespace: '0' = article; '0,10' = article and template
local namespace = title.namespace
for _, v in ipairs(split(config.nscat or nsdefault, ',')) do
if namespace == tonumber(v) then
cat = text_code.all_categories[want_warning and 'warning' or catkey]
if catsort and catsort ~= '' and cat:sub(-2) == ']]' then
cat = cat:sub(1, -3) .. '|' .. mw.text.nowiki(usub(catsort, 1, 20)) .. ']]'
end
break
end
end
end
return cat or ''
end
local function message(parms, mcode, is_warning)
-- Return wikitext for an error message, including category if specified
-- for the message type.
-- mcode = numbered table specifying the message:
-- mcode[1] = 'cvt_xxx' (string used as a key to get message info)
-- mcode[2] = 'parm1' (string to replace '$1' if any in message)
-- mcode[3] = 'parm2' (string to replace '$2' if any in message)
-- mcode[4] = 'parm3' (string to replace '$3' if any in message)
local msg
if type(mcode) == 'table' then
if mcode[1] == 'cvt_no_output' then
-- Some errors should cause convert to output an empty string,
-- for example, for an optional field in an infobox.
return ''
end
msg = text_code.all_messages[mcode[1]]
end
parms.have_problem = true
local function subparm(fmt, ...)
local rep = {}
for i, v in ipairs({...}) do
rep['$' .. i] = v
end
return (fmt:gsub('$%d+', rep))
end
if msg then
local parts = {}
local regex, replace = msg.regex, msg.replace
for i = 1, 3 do
local limit = 40
local s = mcode[i + 1]
if s then
if regex and replace then
s = s:gsub(regex, replace)
limit = nil -- allow long "should be" messages
end
-- Escape user input so it does not break the message.
-- To avoid tags (like {{convert|1<math>23</math>|m}}) breaking
-- the mouseover title, any strip marker starting with char(127) is
-- replaced with '...' (text not needing i18n).
local append
local pos = s:find(string.char(127), 1, true)
if pos then
append = '...'
s = s:sub(1, pos - 1)
end
if limit and ulen(s) > limit then
s = usub(s, 1, limit)
append = '...'
end
s = mw.text.nowiki(s) .. (append or '')
else
s = '?'
end
parts['$' .. i] = s
end
local function ispreview()
-- Return true if a prominent message should be shown.
if parms.test == 'preview' or parms.test == 'nopreview' then
-- For testing, can preview a real message or simulate a preview
-- when running automated tests.
return parms.test == 'preview'
end
local success, revid = pcall(function ()
return (parms.frame):preprocess('{{REVISIONID}}') end)
return success and (revid == '')
end
local want_warning = is_warning and
not config.warnings and -- show unobtrusive warnings if config.warnings not configured
not msg.nowarn -- but use msg settings, not standard warning, if specified
local title = string.gsub(msg[1] or 'Missing message', '$%d+', parts)
local text = want_warning and '*' or msg[2] or 'Missing message'
local cat = wanted_category(msg[3], mcode[2], want_warning)
local anchor = msg[4] or ''
local fmtkey = ispreview() and 'cvt_format_preview' or
(want_warning and 'cvt_format2' or msg.format or 'cvt_format')
local fmt = text_code.all_messages[fmtkey] or 'convert: bug'
return subparm(fmt, title:gsub('"', '"'), text, cat, anchor)
end
return 'Convert internal error: unknown message'
end
function add_warning(parms, level, key, text1, text2) -- for forward declaration above
-- If enabled, add a warning that will be displayed after the convert result.
-- A higher level is more verbose: more kinds of warnings are displayed.
-- To reduce output noise, only the first warning is displayed.
if level <= (tonumber(config.warnings) or 1) then
if parms.warnings == nil then
parms.warnings = message(parms, { key, text1, text2 }, true)
end
end
end
local function spell_number(parms, inout, number, numerator, denominator)
-- Return result of spelling (number, numerator, denominator), or
-- return nil if spelling is not available or not supported for given text.
-- Examples (each value must be a string or nil):
-- number numerator denominator output
-- ------ --------- ----------- -------------------
-- "1.23" nil nil one point two three
-- "1" "2" "3" one and two thirds
-- nil "2" "3" two thirds
if not speller then
local function get_speller(module)
return require(module).spell_number
end
local success
success, speller = pcall(get_speller, spell_module)
if not success or type(speller) ~= 'function' then
add_warning(parms, 1, 'cvt_no_spell', 'spell')
return nil
end
end
local case
if parms.spell_upper == inout then
case = true
parms.spell_upper = nil -- only uppercase first word in a multiple unit
end
local sp = not parms.opt_sp_us
local adj = parms.opt_adjectival
return speller(number, numerator, denominator, case, sp, adj)
end
------------------------------------------------------------------------
-- BEGIN: Code required only for built-in units.
-- LATER: If need much more code, move to another module to simplify this module.
local function speed_of_sound(altitude)
-- This is for the Mach built-in unit of speed.
-- Return speed of sound in metres per second at given altitude in feet.
-- If no altitude given, use default (zero altitude = sea level).
-- Table gives speed of sound in miles per hour at various altitudes:
-- altitude = -17,499 to 402,499 feet
-- mach_table[a + 4] = s where
-- a = (altitude / 5000) rounded to nearest integer (-3 to 80)
-- s = speed of sound (mph) at that altitude
-- LATER: Should calculate result from an interpolation between the next
-- lower and higher altitudes in table, rather than rounding to nearest.
-- From: http://www.aerospaceweb.org/question/atmosphere/q0112.shtml
local mach_table = { -- a =
799.5, 787.0, 774.2, 761.207051, -- -3 to 0
748.0, 734.6, 721.0, 707.0, 692.8, 678.3, 663.5, 660.1, 660.1, 660.1, -- 1 to 10
660.1, 660.1, 660.1, 662.0, 664.3, 666.5, 668.9, 671.1, 673.4, 675.6, -- 11 to 20
677.9, 683.7, 689.9, 696.0, 702.1, 708.1, 714.0, 719.9, 725.8, 731.6, -- 21 to 30
737.3, 737.7, 737.7, 736.2, 730.5, 724.6, 718.8, 712.9, 707.0, 701.0, -- 31 to 40
695.0, 688.9, 682.8, 676.6, 670.4, 664.1, 657.8, 652.9, 648.3, 643.7, -- 41 to 50
639.1, 634.4, 629.6, 624.8, 620.0, 615.2, 613.2, 613.2, 613.2, 613.5, -- 51 to 60
614.4, 615.3, 616.7, 619.8, 623.4, 629.7, 635.0, 641.1, 650.6, 660.0, -- 61 to 70
672.5, 674.3, 676.1, 677.9, 679.7, 681.5, 683.3, 685.1, 686.8, 688.6, -- 71 to 80
}
altitude = altitude or 0
local a = (altitude < 0) and -altitude or altitude
a = floor(a / 5000 + 0.5)
if altitude < 0 then
a = -a
end
if a < -3 then
a = -3
elseif a > 80 then
a = 80
end
return mach_table[a + 4] * 0.44704 -- mph converted to m/s
end
-- END: Code required only for built-in units.
------------------------------------------------------------------------
local function add_style(parms, class)
-- Add selected template style to parms if not already present.
parms.templatestyles = parms.templatestyles or {}
if not parms.templatestyles[class] then
parms.templatestyles[class] = parms.frame:extensionTag({
name = 'templatestyles', args = { src = text_code.titles[class] }
})
end
end
local function get_styles(parms)
-- Return string of required template styles, empty if none.
if parms.templatestyles then
local t = {}
for _, v in pairs(parms.templatestyles) do
table.insert(t, v)
end
return table.concat(t)
end
return ''
end
local function get_range(word)
-- Return a range (string or table) corresponding to word (like "to"),
-- or return nil if not a range word.
local ranges = text_code.ranges
return ranges.types[word] or ranges.types[ranges.aliases[word]]
end
local function check_mismatch(unit1, unit2)
-- If unit1 cannot be converted to unit2, return an error message table.
-- This allows conversion between units of the same type, and between
-- Nm (normally torque) and ftlb (energy), as in gun-related articles.
-- This works because Nm is the base unit (scale = 1) for both the
-- primary type (torque), and the alternate type (energy, where Nm = J).
-- A match occurs if the primary types are the same, or if unit1 matches
-- the alternate type of unit2, and vice versa. That provides a whitelist
-- of which conversions are permitted between normally incompatible types.
if unit1.utype == unit2.utype or
(unit1.utype == unit2.alttype and unit1.alttype == unit2.utype) then
return nil
end
return { 'cvt_mismatch', unit1.utype, unit2.utype }
end
local function override_from(out_table, in_table, fields)
-- Copy the specified fields from in_table to out_table, but do not
-- copy nil fields (keep any corresponding field in out_table).
for _, field in ipairs(fields) do
if in_table[field] then
out_table[field] = in_table[field]
end
end
end
local function shallow_copy(t)
-- Return a shallow copy of table t.
-- Do not need the features and overhead of the Scribunto mw.clone().
local result = {}
for k, v in pairs(t) do
result[k] = v
end
return result
end
local unit_mt = {
-- Metatable to get missing values for a unit that does not accept SI prefixes.
-- Warning: The boolean value 'false' is returned for any missing field
-- so __index is not called twice for the same field in a given unit.
__index = function (self, key)
local value
if key == 'name1' or key == 'sym_us' then
value = self.symbol
elseif key == 'name2' then
value = self.name1 .. plural_suffix
elseif key == 'name1_us' then
value = self.name1
if not rawget(self, 'name2_us') then
-- If name1_us is 'foot', do not make name2_us by appending plural_suffix.
self.name2_us = self.name2
end
elseif key == 'name2_us' then
local raw1_us = rawget(self, 'name1_us')
if raw1_us then
value = raw1_us .. plural_suffix
else
value = self.name2
end
elseif key == 'link' then
value = self.name1
else
value = false
end
rawset(self, key, value)
return value
end
}
local function prefixed_name(unit, name, index)
-- Return unit name with SI prefix inserted at correct position.
-- index = 1 (name1), 2 (name2), 3 (name1_us), 4 (name2_us).
-- The position is a byte (not character) index, so use Lua's sub().
local pos = rawget(unit, 'prefix_position')
if type(pos) == 'string' then
pos = tonumber(split(pos, ',')[index])
end
if pos then
return name:sub(1, pos - 1) .. unit.si_name .. name:sub(pos)
end
return unit.si_name .. name
end
local unit_prefixed_mt = {
-- Metatable to get missing values for a unit that accepts SI prefixes.
-- Before use, fields si_name, si_prefix must be defined.
-- The unit must define _symbol, _name1 and
-- may define _sym_us, _name1_us, _name2_us
-- (_sym_us, _name2_us may be defined for a language using sp=us
-- to refer to a variant unrelated to U.S. units).
__index = function (self, key)
local value
if key == 'symbol' then
value = self.si_prefix .. self._symbol
elseif key == 'sym_us' then
value = rawget(self, '_sym_us')
if value then
value = self.si_prefix .. value
else
value = self.symbol
end
elseif key == 'name1' then
value = prefixed_name(self, self._name1, 1)
elseif key == 'name2' then
value = rawget(self, '_name2')
if value then
value = prefixed_name(self, value, 2)
else
value = self.name1 .. plural_suffix
end
elseif key == 'name1_us' then
value = rawget(self, '_name1_us')
if value then
value = prefixed_name(self, value, 3)
else
value = self.name1
end
elseif key == 'name2_us' then
value = rawget(self, '_name2_us')
if value then
value = prefixed_name(self, value, 4)
elseif rawget(self, '_name1_us') then
value = self.name1_us .. plural_suffix
else
value = self.name2
end
elseif key == 'link' then
value = self.name1
else
value = false
end
rawset(self, key, value)
return value
end
}
local unit_per_mt = {
-- Metatable to get values for a per unit of form "x/y".
-- This is never called to determine a unit name or link because per units
-- are handled as a special case.
-- Similarly, the default output is handled elsewhere, and for a symbol
-- this is only called from get_default() for default_exceptions.
__index = function (self, key)
local value
if key == 'symbol' then
local per = self.per
local unit1, unit2 = per[1], per[2]
if unit1 then
value = unit1[key] .. '/' .. unit2[key]
else
value = '/' .. unit2[key]
end
elseif key == 'sym_us' then
value = self.symbol
elseif key == 'scale' then
local per = self.per
local unit1, unit2 = per[1], per[2]
value = (unit1 and unit1.scale or 1) * self.scalemultiplier / unit2.scale
else
value = false
end
rawset(self, key, value)
return value
end
}
local function make_per(unitcode, unit_table, ulookup)
-- Return true, t where t is a per unit with unit codes expanded to unit tables,
-- or return false, t where t is an error message table.
local result = {
unitcode = unitcode,
utype = unit_table.utype,
per = {}
}
override_from(result, unit_table, { 'invert', 'iscomplex', 'default', 'link', 'symbol', 'symlink' })
result.symbol_raw = (result.symbol or false) -- to distinguish between a defined exception and a metatable calculation
local prefix
for i, v in ipairs(unit_table.per) do
if i == 1 and v == '' then
-- First unit symbol can be empty; that gives a nil first unit table.
elseif i == 1 and text_code.currency[v] then
prefix = currency_text or v
else
local success, t = ulookup(v)
if not success then return false, t end
result.per[i] = t
end
end
local multiplier = unit_table.multiplier
if not result.utype then
-- Creating an automatic per unit.
local unit1 = result.per[1]
local utype = (unit1 and unit1.utype or prefix or '') .. '/' .. result.per[2].utype
local t = data_code.per_unit_fixups[utype]
if t then
if type(t) == 'table' then
utype = t.utype or utype
result.link = result.link or t.link
multiplier = multiplier or t.multiplier
else
utype = t
end
end
result.utype = utype
end
result.scalemultiplier = multiplier or 1
result.vprefix = prefix or false -- set to non-nil to avoid calling __index
return true, setmetatable(result, unit_per_mt)
end
local function lookup(parms, unitcode, what, utable, fails, depth)
-- Return true, t where t is a copy of the unit's converter table,
-- or return false, t where t is an error message table.
-- Parameter 'what' determines whether combination units are accepted:
-- 'no_combination' : single unit only
-- 'any_combination' : single unit or combination or output multiple
-- 'only_multiple' : single unit or output multiple only
-- Parameter unitcode is a symbol (like 'g'), with an optional SI prefix (like 'kg').
-- If, for example, 'kg' is in this table, that entry is used;
-- otherwise the prefix ('k') is applied to the base unit ('g').
-- If unitcode is a known combination code (and if allowed by what),
-- a table of output multiple unit tables is included in the result.
-- For compatibility with the old template, an underscore in a unitcode is
-- replaced with a space so usage like {{convert|350|board_feet}} works.
-- Wikignomes may also put two spaces or " " in combinations, so
-- replace underscore, " ", and multiple spaces with a single space.
utable = utable or parms.unittable or all_units
fails = fails or {}
depth = depth and depth + 1 or 1
if depth > 9 then
-- There are ways to mistakenly define units which result in infinite
-- recursion when lookup() is called. That gives a long delay and very
-- confusing error messages, so the depth parameter is used as a guard.
return false, { 'cvt_lookup', unitcode }
end
if unitcode == nil or unitcode == '' then
return false, { 'cvt_no_unit' }
end
unitcode = unitcode:gsub('_', ' '):gsub(' ', ' '):gsub(' +', ' ')
local function call_make_per(t)
return make_per(unitcode, t,
function (ucode) return lookup(parms, ucode, 'no_combination', utable, fails, depth) end
)
end
local t = utable[unitcode]
if t then
if t.shouldbe then
return false, { 'cvt_should_be', t.shouldbe }
end
if t.sp_us then
parms.opt_sp_us = true
end
local target = t.target -- nil, or unitcode is an alias for this target
if target then
local success, result = lookup(parms, target, what, utable, fails, depth)
if not success then return false, result end
override_from(result, t, { 'customary', 'default', 'link', 'symbol', 'symlink' })
local multiplier = t.multiplier
if multiplier then
result.multiplier = tostring(multiplier)
result.scale = result.scale * multiplier
end
return true, result
end
if t.per then
return call_make_per(t)
end
local combo = t.combination -- nil or a table of unitcodes
if combo then
local multiple = t.multiple
if what == 'no_combination' or (what == 'only_multiple' and not multiple) then
return false, { 'cvt_bad_unit', unitcode }
end
-- Recursively create a combination table containing the
-- converter table of each unitcode.
local result = { utype = t.utype, multiple = multiple, combination = {} }
local cvt = result.combination
for i, v in ipairs(combo) do
local success, t = lookup(parms, v, multiple and 'no_combination' or 'only_multiple', utable, fails, depth)
if not success then return false, t end
cvt[i] = t
end
return true, result
end
local result = shallow_copy(t)
result.unitcode = unitcode
if result.prefixes then
result.si_name = ''
result.si_prefix = ''
return true, setmetatable(result, unit_prefixed_mt)
end
return true, setmetatable(result, unit_mt)
end
local SIprefixes = text_code.SIprefixes
for plen = SIprefixes[1] or 2, 1, -1 do
-- Look for an SI prefix; should never occur with an alias.
-- Check for longer prefix first ('dam' is decametre).
-- SIprefixes[1] = prefix maximum #characters (as seen by mw.ustring.sub).
local prefix = usub(unitcode, 1, plen)
local si = SIprefixes[prefix]
if si then
local t = utable[usub(unitcode, plen+1)]
if t and t.prefixes then
local result = shallow_copy(t)
result.unitcode = unitcode
result.si_name = parms.opt_sp_us and si.name_us or si.name
result.si_prefix = si.prefix or prefix
result.scale = t.scale * 10 ^ (si.exponent * t.prefixes)
return true, setmetatable(result, unit_prefixed_mt)
end
end
end
-- Accept user-defined combinations like "acre+m2+ha" or "acre m2 ha" for output.
-- If '+' is used, each unit code can include a space, and any error is fatal.
-- If ' ' is used and if each space-separated word is a unit code, it is a combo,
-- but errors are not fatal so the unit code can be looked up as an extra unit.
local err_is_fatal
local combo = collection()
if unitcode:find('+', 1, true) then
err_is_fatal = true
for item in (unitcode .. '+'):gmatch('%s*(.-)%s*%+') do
if item ~= '' then
combo:add(item)
end
end
elseif unitcode:find('%s') then
for item in unitcode:gmatch('%S+') do
combo:add(item)
end
end
if combo.n > 1 then
local function lookup_combo()
if what == 'no_combination' or what == 'only_multiple' then
return false, { 'cvt_bad_unit', unitcode }
end
local result = { combination = {} }
local cvt = result.combination
for i, v in ipairs(combo) do
local success, t = lookup(parms, v, 'only_multiple', utable, fails, depth)
if not success then return false, t end
if i == 1 then
result.utype = t.utype
else
local mismatch = check_mismatch(result, t)
if mismatch then
return false, mismatch
end
end
cvt[i] = t
end
return true, result
end
local success, result = lookup_combo()
if success or err_is_fatal then
return success, result
end
end
-- Accept any unit with an engineering notation prefix like "e6cuft"
-- (million cubic feet), but not chained prefixes like "e3e6cuft",
-- and not if the unit is a combination or multiple,
-- and not if the unit has an offset or is a built-in.
-- Only en digits are accepted.
local exponent, baseunit = unitcode:match('^e(%d+)(.*)')
if exponent then
local engscale = text_code.eng_scales[exponent]
if engscale then
local success, result = lookup(parms, baseunit, 'no_combination', utable, fails, depth)
if success and not (result.offset or result.builtin or result.engscale) then
result.unitcode = unitcode -- 'e6cuft' not 'cuft'
result.defkey = unitcode -- key to lookup default exception
result.engscale = engscale
result.scale = result.scale * 10 ^ tonumber(exponent)
return true, result
end
end
end
-- Look for x/y; split on right-most slash to get scale correct (x/y/z is x/y per z).
local top, bottom = unitcode:match('^(.-)/([^/]+)$')
if top and not unitcode:find('e%d') then
-- If valid, create an automatic per unit for an "x/y" unit code.
-- The unitcode must not include extraneous spaces.
-- Engineering notation (apart from at start and which has been stripped before here),
-- is not supported so do not make a per unit if find text like 'e3' in unitcode.
local success, result = call_make_per({ per = {top, bottom} })
if success then
return true, result
end
end
if not parms.opt_ignore_error and not get_range(unitcode) then
-- Want the "what links here" list for the extra_module to show only cases
-- where an extra unit is used, so do not require it if invoked from {{val}}
-- or if looking up a range word which cannot be a unit.
if not extra_units then
local success, extra = pcall(function () return require(extra_module).extra_units end)
if success and type(extra) == 'table' then
extra_units = extra
end
end
if extra_units then
-- A unit in one data table might refer to a unit in the other table, so
-- switch between them, relying on fails or depth to terminate loops.
if not fails[unitcode] then
fails[unitcode] = true
local other = (utable == all_units) and extra_units or all_units
local success, result = lookup(parms, unitcode, what, other, fails, depth)
if success then
return true, result
end
end
end
end
if to_en_table then
-- At fawiki it is common to translate all digits so a unit like "km2" becomes "km۲".
local en_code = ustring.gsub(unitcode, '%d', to_en_table)
if en_code ~= unitcode then
return lookup(parms, en_code, what, utable, fails, depth)
end
end
return false, { 'cvt_unknown', unitcode }
end
local function valid_number(num)
-- Return true if num is a valid number.
-- In Scribunto (different from some standard Lua), when expressed as a string,
-- overflow or other problems are indicated with text like "inf" or "nan"
-- which are regarded as invalid here (each contains "n").
if type(num) == 'number' and tostring(num):find('n', 1, true) == nil then
return true
end
end
local function hyphenated(name, parts)
-- Return a hyphenated form of given name (for adjectival usage).
-- The name may be linked and the target of the link must not be changed.
-- Hypothetical examples:
-- [[long ton|ton]] → [[long ton|ton]] (no change)
-- [[tonne|long ton]] → [[tonne|long-ton]]
-- [[metric ton|long ton]] → [[metric ton|long-ton]]
-- [[long ton]] → [[long ton|long-ton]]
-- Input can also have multiple links in a single name like:
-- [[United States customary units|U.S.]] [[US gallon|gallon]]
-- [[mile]]s per [[United States customary units|U.S.]] [[quart]]
-- [[long ton]]s per [[short ton]]
-- Assume that links cannot be nested (never like "[[abc[[def]]ghi]]").
-- This uses a simple and efficient procedure that works for most cases.
-- Some units (if used) would require more, and can later think about
-- adding a method to handle exceptions.
-- The procedure is to replace each space with a hyphen, but
-- not a space after ')' [for "(pre-1954 US) nautical mile"], and
-- not spaces immediately before '(' or in '(...)' [for cases like
-- "British thermal unit (ISO)" and "Calorie (International Steam Table)"].
if name:find(' ', 1, true) then
if parts then
local pos
if name:sub(1, 1) == '(' then
pos = name:find(')', 1, true)
if pos then
return name:sub(1, pos+1) .. name:sub(pos+2):gsub(' ', '-')
end
elseif name:sub(-1) == ')' then
pos = name:find('(', 1, true)
if pos then
return name:sub(1, pos-2):gsub(' ', '-') .. name:sub(pos-1)
end
end
return name:gsub(' ', '-')
end
parts = collection()
for before, item, after in name:gmatch('([^[]*)(%[%[[^[]*%]%])([^[]*)') do
if item:find(' ', 1, true) then
local prefix
local plen = item:find('|', 1, true)
if plen then
prefix = item:sub(1, plen)
item = item:sub(plen + 1, -3)
else
prefix = item:sub(1, -3) .. '|'
item = item:sub(3, -3)
end
item = prefix .. hyphenated(item, parts) .. ']]'
end
parts:add(before:gsub(' ', '-') .. item .. after:gsub(' ', '-'))
end
if parts.n == 0 then
-- No link like "[[...]]" was found in the original name.
parts:add(hyphenated(name, parts))
end
return table.concat(parts)
end
return name
end
local function hyphenated_maybe(parms, want_name, sep, id, inout)
-- Return s, f where
-- s = id, possibly modified
-- f = true if hyphenated
-- Possible modifications: hyphenate; prepend '-'; append mid text.
if id == nil or id == '' then
return ''
end
local mid = (inout == (parms.opt_flip and 'out' or 'in')) and parms.mid or ''
if want_name then
if parms.opt_adjectival then
return '-' .. hyphenated(id) .. mid, true
end
if parms.opt_add_s and id:sub(-1) ~= 's' then
id = id .. 's' -- for nowiki
end
end
return sep .. id .. mid
end
local function use_minus(text)
-- Return text with Unicode minus instead of '-', if present.
if text:sub(1, 1) == '-' then
return MINUS .. text:sub(2)
end
return text
end
local function digit_groups(parms, text, method)
-- Return a numbered table of groups of digits (left-to-right, in local language).
-- Parameter method is a number or nil:
-- 3 for 3-digit grouping (default), or
-- 2 for 3-then-2 grouping (only for digits before decimal mark).
local len_right
local len_left = text:find('.', 1, true)
if len_left then
len_right = #text - len_left
len_left = len_left - 1
else
len_left = #text
end
local twos = method == 2 and len_left > 5
local groups = collection()
local run = len_left
local n
if run < 4 or (run == 4 and parms.opt_comma5) then
if parms.opt_gaps then
n = run
else
n = #text
end
elseif twos then
n = run % 2 == 0 and 1 or 2
else
n = run % 3 == 0 and 3 or run % 3
end
while run > 0 do
groups:add(n)
run = run - n
n = (twos and run > 3) and 2 or 3
end
if len_right then
if groups.n == 0 then
groups:add(0)
end
if parms.opt_gaps and len_right > 3 then
local want4 = not parms.opt_gaps3 -- true gives no gap before trailing single digit
local isfirst = true
run = len_right
while run > 0 do
n = (want4 and run == 4) and 4 or (run > 3 and 3 or run)
if isfirst then
isfirst = false
groups[groups.n] = groups[groups.n] + 1 + n
else
groups:add(n)
end
run = run - n
end
else
groups[groups.n] = groups[groups.n] + 1 + len_right
end
end
local pos = 1
for i, length in ipairs(groups) do
groups[i] = from_en(text:sub(pos, pos + length - 1))
pos = pos + length
end
return groups
end
function with_separator(parms, text) -- for forward declaration above
-- Input text is a number in en digits with optional '.' decimal mark.
-- Return an equivalent, formatted for display:
-- with a custom decimal mark instead of '.', if wanted
-- with thousand separators inserted, if wanted
-- digits in local language
-- The given text is like '123' or '123.' or '12345.6789'.
-- The text has no sign (caller inserts that later, if necessary).
-- When using gaps, they are inserted before and after the decimal mark.
-- Separators are inserted only before the decimal mark.
-- A trailing dot (as in '123.') is removed because their use appears to
-- be accidental, and such a number should be shown as '123' or '123.0'.
-- It is useful for convert to suppress the dot so, for example, '4000.'
-- is a simple way of indicating that all the digits are significant.
if text:sub(-1) == '.' then
text = text:sub(1, -2)
end
if #text < 4 or parms.opt_nocomma or numsep == '' then
return from_en(text)
end
local groups = digit_groups(parms, text, group_method)
if parms.opt_gaps then
if groups.n <= 1 then
return groups[1] or ''
end
local nowrap = '<span style="white-space: nowrap">'
local gap = '<span style="margin-left: 0.25em">'
local close = '</span>'
return nowrap .. groups[1] .. gap .. table.concat(groups, close .. gap, 2, groups.n) .. close .. close
end
return table.concat(groups, numsep)
end
-- An input value like 1.23e12 is displayed using scientific notation (1.23×10¹²).
-- That also makes the output use scientific notation, except for small values.
-- In addition, very small or very large output values use scientific notation.
-- Use format(fmtpower, significand, '10', exponent) where each argument is a string.
local fmtpower = '%s<span style="margin:0 .15em 0 .25em">×</span>%s<sup>%s</sup>'
local function with_exponent(parms, show, exponent)
-- Return wikitext to display the implied value in scientific notation.
-- Input uses en digits; output uses digits in local language.
return format(fmtpower, with_separator(parms, show), from_en('10'), use_minus(from_en(tostring(exponent))))
end
local function make_sigfig(value, sigfig)
-- Return show, exponent that are equivalent to the result of
-- converting the number 'value' (where value >= 0) to a string,
-- rounded to 'sigfig' significant figures.
-- The returned items are:
-- show: a string of digits; no sign and no dot;
-- there is an implied dot before show.
-- exponent: a number (an integer) to shift the implied dot.
-- Resulting value = tonumber('.' .. show) * 10^exponent.
-- Examples:
-- make_sigfig(23.456, 3) returns '235', 2 (.235 * 10^2).
-- make_sigfig(0.0023456, 3) returns '235', -2 (.235 * 10^-2).
-- make_sigfig(0, 3) returns '000', 1 (.000 * 10^1).
if sigfig <= 0 then
sigfig = 1
elseif sigfig > maxsigfig then
sigfig = maxsigfig
end
if value == 0 then
return string.rep('0', sigfig), 1
end
local exp, fracpart = math.modf(log10(value))
if fracpart >= 0 then
fracpart = fracpart - 1
exp = exp + 1
end
local digits = format('%.0f', 10^(fracpart + sigfig))
if #digits > sigfig then
-- Overflow (for sigfig=3: like 0.9999 rounding to "1000"; need "100").
digits = digits:sub(1, sigfig)
exp = exp + 1
end
assert(#digits == sigfig, 'Bug: rounded number has wrong length')
return digits, exp
end
-- Fraction output format.
local fracfmt = {
{ -- Like {{frac}} (fraction slash).
'<span class="frac" role="math">{SIGN}<span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1/2
'<span class="frac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1+2/3
style = 'frac',
},
{ -- Like {{sfrac}} (stacked fraction, that is, horizontal bar).
'<span class="sfrac tion" role="math">{SIGN}<span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span>', -- 1//2
'<span class="sfrac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="tion"><span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span></span>', -- 1+2//3
style = 'sfrac',
},
}
local function format_fraction(parms, inout, negative, wholestr, numstr, denstr, do_spell, style)
-- Return wikitext for a fraction, possibly spelled.
-- Inputs use en digits and have no sign; output uses digits in local language.
local wikitext
if not style then
style = parms.opt_fraction_horizontal and 2 or 1
end
if wholestr == '' then
wholestr = nil
end
local substitute = {
SIGN = negative and MINUS or '',
WHOLE = wholestr and with_separator(parms, wholestr),
NUM = from_en(numstr),
DEN = from_en(denstr),
}
wikitext = fracfmt[style][wholestr and 2 or 1]:gsub('{(%u+)}', substitute)
if do_spell then
if negative then
if wholestr then
wholestr = '-' .. wholestr
else
numstr = '-' .. numstr
end
end
local s = spell_number(parms, inout, wholestr, numstr, denstr)
if s then
return s
end
end
add_style(parms, fracfmt[style].style)
return wikitext
end
local function format_number(parms, show, exponent, isnegative)
-- Parameter show is a string or a table containing strings.
-- Each string is a formatted number in en digits and optional '.' decimal mark.
-- A table represents a fraction: integer, numerator, denominator;
-- if a table is given, exponent must be nil.
-- Return t where t is a table with fields:
-- show = wikitext formatted to display implied value
-- (digits in local language)
-- is_scientific = true if show uses scientific notation
-- clean = unformatted show (possibly adjusted and with inserted '.')
-- (en digits)
-- sign = '' or MINUS
-- exponent = exponent (possibly adjusted)
-- The clean and exponent fields can be used to calculate the
-- rounded absolute value, if needed.
--
-- The value implied by the arguments is found from:
-- exponent is nil; and
-- show is a string of digits (no sign), with an optional dot;
-- show = '123.4' is value 123.4, '1234' is value 1234.0;
-- or:
-- exponent is an integer indicating where dot should be;
-- show is a string of digits (no sign and no dot);
-- there is an implied dot before show;
-- show does not start with '0';
-- show = '1234', exponent = 3 is value 0.1234*10^3 = 123.4.
--
-- The formatted result:
-- * Is for an output value and is spelled if wanted and possible.
-- * Includes a Unicode minus if isnegative and not spelled.
-- * Uses a custom decimal mark, if wanted.
-- * Has digits grouped where necessary, if wanted.
-- * Uses scientific notation if requested, or for very small or large values
-- (which forces result to not be spelled).
-- * Has no more than maxsigfig significant digits
-- (same as old template and {{#expr}}).
local xhi, xlo -- these control when scientific notation (exponent) is used
if parms.opt_scientific then
xhi, xlo = 4, 2 -- default for output if input uses e-notation
elseif parms.opt_scientific_always then
xhi, xlo = 0, 0 -- always use scientific notation (experimental)
else
xhi, xlo = 10, 4 -- default
end
local sign = isnegative and MINUS or ''
local maxlen = maxsigfig
local tfrac
if type(show) == 'table' then
tfrac = show
show = tfrac.wholestr
assert(exponent == nil, 'Bug: exponent given with fraction')
end
if not tfrac and not exponent then
local integer, dot, decimals = show:match('^(%d*)(%.?)(.*)')
if integer == '0' or integer == '' then
local zeros, figs = decimals:match('^(0*)([^0]?.*)')
if #figs == 0 then
if #zeros > maxlen then
show = '0.' .. zeros:sub(1, maxlen)
end
elseif #zeros >= xlo then
show = figs
exponent = -#zeros
elseif #figs > maxlen then
show = '0.' .. zeros .. figs:sub(1, maxlen)
end
elseif #integer >= xhi then
show = integer .. decimals
exponent = #integer
else
maxlen = maxlen + #dot
if #show > maxlen then
show = show:sub(1, maxlen)
end
end
end
if exponent then
local function zeros(n)
return string.rep('0', n)
end
if #show > maxlen then
show = show:sub(1, maxlen)
end
if exponent > xhi or exponent <= -xlo or (exponent == xhi and show ~= '1' .. zeros(xhi - 1)) then
-- When xhi, xlo = 10, 4 (the default), scientific notation is used if the
-- rounded value satisfies: value >= 1e9 or value < 1e-4 (1e9 = 0.1e10),
-- except if show is '1000000000' (1e9), for example:
-- {{convert|1000000000|m|m|sigfig=10}} → 1,000,000,000 metres (1,000,000,000 m)
local significand
if #show > 1 then
significand = show:sub(1, 1) .. '.' .. show:sub(2)
else
significand = show
end
return {
clean = '.' .. show,
exponent = exponent,
sign = sign,
show = sign .. with_exponent(parms, significand, exponent-1),
is_scientific = true,
}
end
if exponent >= #show then
show = show .. zeros(exponent - #show) -- result has no dot
elseif exponent <= 0 then
show = '0.' .. zeros(-exponent) .. show
else
show = show:sub(1, exponent) .. '.' .. show:sub(exponent+1)
end
end
local formatted_show
if tfrac then
show = tostring(tfrac.value) -- to set clean in returned table
formatted_show = format_fraction(parms, 'out', isnegative, tfrac.wholestr, tfrac.numstr, tfrac.denstr, parms.opt_spell_out)
else
if isnegative and show:match('^0.?0*$') then
sign = '' -- don't show minus if result is negative but rounds to zero
end
formatted_show = sign .. with_separator(parms, show)
if parms.opt_spell_out then
formatted_show = spell_number(parms, 'out', sign .. show) or formatted_show
end
end
return {
clean = show,
sign = sign,
show = formatted_show,
is_scientific = false, -- to avoid calling __index
}
end
local function extract_fraction(parms, text, negative)
-- If text represents a fraction, return
-- value, altvalue, show, denominator
-- where
-- value is a number (value of the fraction in argument text)
-- altvalue is an alternate interpretation of any fraction for the hands
-- unit where "12.1+3/4" means 12 hands 1.75 inches
-- show is a string (formatted text for display of an input value,
-- and is spelled if wanted and possible)
-- denominator is value of the denominator in the fraction
-- Otherwise, return nil.
-- Input uses en digits and '.' decimal mark (input has been translated).
-- Output uses digits in local language and local decimal mark, if any.
------------------------------------------------------------------------
-- Originally this function accepted x+y/z where x, y, z were any valid
-- numbers, possibly with a sign. For example '1.23e+2+1.2/2.4' = 123.5,
-- and '2-3/8' = 1.625. However, such usages were found to be errors or
-- misunderstandings, so since August 2014 the following restrictions apply:
-- x (if present) is an integer or has a single digit after decimal mark
-- y and z are unsigned integers
-- e-notation is not accepted
-- The overall number can start with '+' or '-' (so '12+3/4' and '+12+3/4'
-- and '-12-3/4' are valid).
-- Any leading negative sign is removed by the caller, so only inputs
-- like the following are accepted here (may have whitespace):
-- negative = false false true (there was a leading '-')
-- text = '2/3' '+2/3' '2/3'
-- text = '1+2/3' '+1+2/3' '1-2/3'
-- text = '12.3+1/2' '+12.3+1/2' '12.3-1/2'
-- Values like '12.3+1/2' are accepted, but are intended only for use
-- with the hands unit (not worth adding code to enforce that).
------------------------------------------------------------------------
local leading_plus, prefix, numstr, slashes, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*(/+)%s*(%d+)%s*$')
if not leading_plus then
-- Accept a single U+2044 fraction slash because that may be pasted.
leading_plus, prefix, numstr, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*⁄%s*(%d+)%s*$')
slashes = '/'
end
local numerator = tonumber(numstr)
local denominator = tonumber(denstr)
if numerator == nil or denominator == nil or (negative and leading_plus ~= '') then
return nil
end
local whole, wholestr
if prefix == '' then
wholestr = ''
whole = 0
else
-- Any prefix must be like '12+' or '12-' (whole number and fraction sign);
-- '12.3+' and '12.3-' are also accepted (single digit after decimal point)
-- because '12.3+1/2 hands' is valid (12 hands 3½ inches).
local num1, num2, frac_sign = prefix:match('^(%d+)(%.?%d?)%s*([+%-])$')
if num1 == nil then return nil end
if num2 == '' then -- num2 must be '' or like '.1' but not '.' or '.12'
wholestr = num1
else
if #num2 ~= 2 then return nil end
wholestr = num1 .. num2
end
if frac_sign ~= (negative and '-' or '+') then return nil end
whole = tonumber(wholestr)
if whole == nil then return nil end
end
local value = whole + numerator / denominator
if not valid_number(value) then return nil end
local altvalue = whole + numerator / (denominator * 10)
local style = #slashes -- kludge: 1 or 2 slashes can be used to select style
if style > 2 then style = 2 end
local wikitext = format_fraction(parms, 'in', negative, leading_plus .. wholestr, numstr, denstr, parms.opt_spell_in, style)
return value, altvalue, wikitext, denominator
end
local function extract_number(parms, text, another, no_fraction)
-- Return true, info if can extract a number from text,
-- where info is a table with the result,
-- or return false, t where t is an error message table.
-- Input can use en digits or digits in local language and can
-- have references at the end. Accepting references is intended
-- for use in infoboxes with a field for a value passed to convert.
-- Parameter another = true if the expected value is not the first.
-- Before processing, the input text is cleaned:
-- * Any thousand separators (valid or not) are removed.
-- * Any sign is replaced with '-' (if negative) or '' (otherwise).
-- That replaces Unicode minus with '-'.
-- If successful, the returned info table contains named fields:
-- value = a valid number
-- altvalue = a valid number, usually same as value but different
-- if fraction used (for hands unit)
-- singular = true if value is 1 or -1 (to use singular form of units)
-- clean = cleaned text with any separators and sign removed
-- (en digits and '.' decimal mark)
-- show = text formatted for output, possibly with ref strip markers
-- (digits in local language and custom decimal mark)
-- The resulting show:
-- * Is for an input value and is spelled if wanted and possible.
-- * Has a rounded value, if wanted.
-- * Has digits grouped where necessary, if wanted.
-- * If negative, a Unicode minus is used; otherwise the sign is
-- '+' (if the input text used '+'), or is '' (if no sign in input).
text = strip(text or '')
local reference
local pos = text:find('\127', 1, true)
if pos then
local before = text:sub(1, pos - 1)
local remainder = text:sub(pos)
local refs = {}
while #remainder > 0 do
local ref, spaces
ref, spaces, remainder = remainder:match('^(\127[^\127]*UNIQ[^\127]*%-ref[^\127]*\127)(%s*)(.*)')
if ref then
table.insert(refs, ref)
else
refs = {}
break
end
end
if #refs > 0 then
text = strip(before)
reference = table.concat(refs)
end
end
local clean = to_en(text, parms)
if clean == '' then
return false, { another and 'cvt_no_num2' or 'cvt_no_num' }
end
local isnegative, propersign = false, '' -- most common case
local singular, show, denominator
local value = tonumber(clean)
local altvalue
if value then
local sign = clean:sub(1, 1)
if sign == '+' or sign == '-' then
propersign = (sign == '+') and '+' or MINUS
clean = clean:sub(2)
end
if value < 0 then
isnegative = true
value = -value
end
else
local valstr
for _, prefix in ipairs({ '-', MINUS, '−' }) do
-- Including '-' sets isnegative in case input is a fraction like '-2-3/4'.
local plen = #prefix
if clean:sub(1, plen) == prefix then
valstr = clean:sub(plen + 1)
if valstr:match('^%s') then -- "- 1" is invalid but "-1 - 1/2" is ok
return false, { 'cvt_bad_num', text }
end
break
end
end
if valstr then
isnegative = true
propersign = MINUS
clean = valstr
value = tonumber(clean)
end
if value == nil then
if not no_fraction then
value, altvalue, show, denominator = extract_fraction(parms, clean, isnegative)
end
if value == nil then
return false, { 'cvt_bad_num', text }
end
if value <= 1 then
singular = true -- for example, "½ mile" or "one half mile" (singular unit)
end
end
end
if not valid_number(value) then -- for example, "1e310" may overflow
return false, { 'cvt_invalid_num' }
end
if show == nil then
-- clean is a non-empty string with no spaces, and does not represent a fraction,
-- and value = tonumber(clean) is a number >= 0.
-- If the input uses e-notation, show will be displayed using a power of ten, but
-- we use the number as given so it might not be normalized scientific notation.
-- The input value is spelled if specified so any e-notation is ignored;
-- that allows input like 2e6 to be spelled as "two million" which works
-- because the spell module converts '2e6' to '2000000' before spelling.
local function rounded(value, default, exponent)
local precision = parms.opt_ri
if precision then
local fmt = '%.' .. format('%d', precision) .. 'f'
local result = fmt:format(tonumber(value) + 2e-14) -- fudge for some common cases of bad rounding
if not exponent then
singular = (tonumber(result) == 1)
end
return result
end
return default
end
singular = (value == 1)
local scientific
local significand, exponent = clean:match('^([%d.]+)[Ee]([+%-]?%d+)')
if significand then
show = with_exponent(parms, rounded(significand, significand, exponent), exponent)
scientific = true
else
show = with_separator(parms, rounded(value, clean))
end
show = propersign .. show
if parms.opt_spell_in then
show = spell_number(parms, 'in', propersign .. rounded(value, clean)) or show
scientific = false
end
if scientific then
parms.opt_scientific = true
end
end
if isnegative and (value ~= 0) then
value = -value
altvalue = -(altvalue or value)
end
return true, {
value = value,
altvalue = altvalue or value,
singular = singular,
clean = clean,
show = show .. (reference or ''),
denominator = denominator,
}
end
local function get_number(text)
-- Return v, f where:
-- v = nil (text is not a number)
-- or
-- v = value of text (text is a number)
-- f = true if value is an integer
-- Input can use en digits or digits in local language or separators,
-- but no Unicode minus, and no fraction.
if text then
local number = tonumber(to_en(text))
if number then
local _, fracpart = math.modf(number)
return number, (fracpart == 0)
end
end
end
local function gcd(a, b)
-- Return the greatest common denominator for the given values,
-- which are known to be positive integers.
if a > b then
a, b = b, a
end
if a <= 0 then
return b
end
local r = b % a
if r <= 0 then
return a
end
if r == 1 then
return 1
end
return gcd(r, a)
end
local function fraction_table(value, denominator)
-- Return value as a string or a table:
-- * If result is a string, there is no fraction, and the result
-- is value formatted as a string of en digits.
-- * If result is a table, it represents a fraction with named fields:
-- wholestr, numstr, denstr (strings of en digits for integer, numerator, denominator).
-- The result is rounded to the nearest multiple of (1/denominator).
-- If the multiple is zero, no fraction is included.
-- No fraction is included if value is very large as the fraction would
-- be unhelpful, particularly if scientific notation is required.
-- Input value is a non-negative number.
-- Input denominator is a positive integer for the desired fraction.
if value <= 0 then
return '0'
end
if denominator <= 0 or value > 1e8 then
return format('%.2f', value)
end
local integer, decimals = math.modf(value)
local numerator = floor((decimals * denominator) +
0.5 + 2e-14) -- add fudge for some common cases of bad rounding
if numerator >= denominator then
integer = integer + 1
numerator = 0
end
local wholestr = tostring(integer)
if numerator > 0 then
local div = gcd(numerator, denominator)
if div > 1 then
numerator = numerator / div
denominator = denominator / div
end
return {
wholestr = (integer > 0) and wholestr or '',
numstr = tostring(numerator),
denstr = tostring(denominator),
value = value,
}
end
return wholestr
end
local function preunits(count, preunit1, preunit2)
-- If count is 1:
-- ignore preunit2
-- return p1
-- else:
-- preunit1 is used for preunit2 if the latter is empty
-- return p1, p2
-- where:
-- p1 is text to insert before the input unit
-- p2 is text to insert before the output unit
-- p1 or p2 may be nil to mean "no preunit"
-- Using '+' gives output like "5+ feet" (no space before, but space after).
local function withspace(text, wantboth)
-- Return text with space before and, if wantboth, after.
-- However, no space is added if there is a space or ' ' or '-'
-- at that position ('-' is for adjectival text).
-- There is also no space if text starts with '&'
-- (e.g. '°' would display a degree symbol with no preceding space).
local char = text:sub(1, 1)
if char == '&' then
return text -- an html entity can be used to specify the exact display
end
if not (char == ' ' or char == '-' or char == '+') then
text = ' ' .. text
end
if wantboth then
char = text:sub(-1, -1)
if not (char == ' ' or char == '-' or text:sub(-6, -1) == ' ') then
text = text .. ' '
end
end
return text
end
local PLUS = '+ '
preunit1 = preunit1 or ''
local trim1 = strip(preunit1)
if count == 1 then
if trim1 == '' then
return nil
end
if trim1 == '+' then
return PLUS
end
return withspace(preunit1, true)
end
preunit1 = withspace(preunit1)
preunit2 = preunit2 or ''
local trim2 = strip(preunit2)
if trim1 == '+' then
if trim2 == '' or trim2 == '+' then
return PLUS, PLUS
end
preunit1 = PLUS
end
if trim2 == '' then
if trim1 == '' then
return nil, nil
end
preunit2 = preunit1
elseif trim2 == '+' then
preunit2 = PLUS
elseif trim2 == ' ' then -- trick to make preunit2 empty
preunit2 = nil
else
preunit2 = withspace(preunit2)
end
return preunit1, preunit2
end
local function range_text(range, want_name, parms, before, after, inout, options)
-- Return before .. rtext .. after
-- where rtext is the text that separates two values in a range.
local rtext, adj_text, exception
options = options or {}
if type(range) == 'table' then
-- Table must specify range text for ('off' and 'on') or ('input' and 'output'),
-- and may specify range text for 'adj=on',
-- and may specify exception = true.
rtext = range[want_name and 'off' or 'on'] or
range[((inout == 'in') == (parms.opt_flip == true)) and 'output' or 'input']
adj_text = range['adj']
exception = range['exception']
else
rtext = range
end
if parms.opt_adjectival then
if want_name or (exception and parms.abbr_org == 'on') then
rtext = adj_text or rtext:gsub(' ', '-'):gsub(' ', '-')
end
end
if rtext == '–' and (options.spaced or after:sub(1, #MINUS) == MINUS) then
rtext = ' – '
end
return before .. rtext .. after
end
local function get_composite(parms, iparm, in_unit_table)
-- Look for a composite input unit. For example, {{convert|1|yd|2|ft|3|in}}
-- would result in a call to this function with
-- iparm = 3 (parms[iparm] = "2", just after the first unit)
-- in_unit_table = (unit table for "yd"; contains value 1 for number of yards)
-- Return true, iparm, unit where
-- iparm = index just after the composite units (7 in above example)
-- unit = composite unit table holding all input units,
-- or return true if no composite unit is present in parms,
-- or return false, t where t is an error message table.
local default, subinfo
local composite_units, count = { in_unit_table }, 1
local fixups = {}
local total = in_unit_table.valinfo[1].value
local subunit = in_unit_table
while subunit.subdivs do -- subdivs is nil or a table of allowed subdivisions
local subcode = strip(parms[iparm+1])
local subdiv = subunit.subdivs[subcode] or subunit.subdivs[(all_units[subcode] or {}).target]
if not subdiv then
break
end
local success
success, subunit = lookup(parms, subcode, 'no_combination')
if not success then return false, subunit end -- should never occur
success, subinfo = extract_number(parms, parms[iparm])
if not success then return false, subinfo end
iparm = iparm + 2
subunit.inout = 'in'
subunit.valinfo = { subinfo }
-- Recalculate total as a number of subdivisions.
-- subdiv[1] = number of subdivisions per previous unit (integer > 1).
total = total * subdiv[1] + subinfo.value
if not default then -- set by the first subdiv with a default defined
default = subdiv.default
end
count = count + 1
composite_units[count] = subunit
if subdiv.unit or subdiv.name then
fixups[count] = { unit = subdiv.unit, name = subdiv.name, valinfo = subunit.valinfo }
end
end
if count == 1 then
return true -- no error and no composite unit
end
for i, fixup in pairs(fixups) do
local unit = fixup.unit
local name = fixup.name
if not unit or (count > 2 and name) then
composite_units[i].fixed_name = name
else
local success, alternate = lookup(parms, unit, 'no_combination')
if not success then return false, alternate end -- should never occur
alternate.inout = 'in'
alternate.valinfo = fixup.valinfo
composite_units[i] = alternate
end
end
return true, iparm, {
utype = in_unit_table.utype,
scale = subunit.scale, -- scale of last (least significant) unit
valinfo = { { value = total, clean = subinfo.clean, denominator = subinfo.denominator } },
composite = composite_units,
default = default or in_unit_table.default
}
end
local function translate_parms(parms, kv_pairs)
-- Update fields in parms by translating each key:value in kv_pairs to terms
-- used by this module (may involve translating from local language to English).
-- Also, checks are performed which may display warnings, if enabled.
-- Return true if successful or return false, t where t is an error message table.
currency_text = nil -- local testing can hold module in memory; must clear globals
if kv_pairs.adj and kv_pairs.sing then
-- For enwiki (before translation), warn if attempt to use adj and sing
-- as the latter is a deprecated alias for the former.
if kv_pairs.adj ~= kv_pairs.sing and kv_pairs.sing ~= '' then
add_warning(parms, 1, 'cvt_unknown_option', 'sing=' .. kv_pairs.sing)
end
kv_pairs.sing = nil
end
kv_pairs.comma = kv_pairs.comma or config.comma -- for plwiki who want default comma=5
for loc_name, loc_value in pairs(kv_pairs) do
local en_name = text_code.en_option_name[loc_name]
if en_name then
local en_value = text_code.en_option_value[en_name]
if en_value == 'INTEGER' then -- altitude_ft, altitude_m, frac, sigfig
en_value = nil
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
else
local minimum
local number, is_integer = get_number(loc_value)
if en_name == 'sigfig' then
minimum = 1
elseif en_name == 'frac' then
minimum = 2
if number and number < 0 then
parms.opt_fraction_horizontal = true
number = -number
end
else
minimum = -1e6
end
if number and is_integer and number >= minimum then
en_value = number
else
local m
if en_name == 'frac' then
m = 'cvt_bad_frac'
elseif en_name == 'sigfig' then
m = 'cvt_bad_sigfig'
else
m = 'cvt_bad_altitude'
end
add_warning(parms, 1, m, loc_name .. '=' .. loc_value)
end
end
elseif en_value == 'TEXT' then -- $, input, qid, qual, stylein, styleout, tracking
en_value = loc_value ~= '' and loc_value or nil -- accept non-empty user text with no validation
if not en_value and (en_name == '$' or en_name == 'qid' or en_name == 'qual') then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
elseif en_name == '$' then
-- Value should be a single character like "€" for the euro currency symbol, but anything is accepted.
currency_text = (loc_value == 'euro') and '€' or loc_value
elseif en_name == 'input' then
-- May have something like {{convert|input=}} (empty input) if source is an infobox
-- with optional fields. In that case, want to output nothing rather than an error.
parms.input_text = loc_value -- keep input because parms.input is nil if loc_value == ''
end
else
en_value = en_value[loc_value]
if en_value and en_value:sub(-1) == '?' then
en_value = en_value:sub(1, -2)
add_warning(parms, -1, 'cvt_deprecated', loc_name .. '=' .. loc_value)
end
if en_value == nil then
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
else
add_warning(parms, 1, 'cvt_unknown_option', loc_name .. '=' .. loc_value)
end
elseif en_value == '' then
en_value = nil -- an ignored option like adj=off
elseif type(en_value) == 'string' and en_value:sub(1, 4) == 'opt_' then
for _, v in ipairs(split(en_value, ',')) do
local lhs, rhs = v:match('^(.-)=(.+)$')
if rhs then
parms[lhs] = tonumber(rhs) or rhs
else
parms[v] = true
end
end
en_value = nil
end
end
parms[en_name] = en_value
else
add_warning(parms, 1, 'cvt_unknown_option', loc_name .. '=' .. loc_value)
end
end
local abbr_entered = parms.abbr
local cfg_abbr = config.abbr
if cfg_abbr then
-- Don't warn if invalid because every convert would show that warning.
if cfg_abbr == 'on always' then
parms.abbr = 'on'
elseif cfg_abbr == 'off always' then
parms.abbr = 'off'
elseif parms.abbr == nil then
if cfg_abbr == 'on default' then
parms.abbr = 'on'
elseif cfg_abbr == 'off default' then
parms.abbr = 'off'
end
end
end
if parms.abbr then
if parms.abbr == 'unit' then
parms.abbr = 'on'
parms.number_word = true
end
parms.abbr_org = parms.abbr -- original abbr, before any flip
elseif parms.opt_hand_hh then
parms.abbr_org = 'on'
parms.abbr = 'on'
else
parms.abbr = 'out' -- default is to abbreviate output only (use symbol, not name)
end
if parms.opt_order_out then
-- Disable options that do not work in a useful way with order=out.
parms.opt_flip = nil -- override adj=flip
parms.opt_spell_in = nil
parms.opt_spell_out = nil
parms.opt_spell_upper = nil
end
if parms.opt_spell_out and not abbr_entered then
parms.abbr = 'off' -- should show unit name when spelling the output value
end
if parms.opt_flip then
local function swap_in_out(option)
local value = parms[option]
if value == 'in' then
parms[option] = 'out'
elseif value == 'out' then
parms[option] = 'in'
end
end
swap_in_out('abbr')
swap_in_out('lk')
if parms.opt_spell_in and not parms.opt_spell_out then
-- For simplicity, and because it does not appear to be needed,
-- user cannot set an option to spell the output only.
parms.opt_spell_in = nil
parms.opt_spell_out = true
end
end
if parms.opt_spell_upper then
parms.spell_upper = parms.opt_flip and 'out' or 'in'
end
if parms.opt_table or parms.opt_tablecen then
if abbr_entered == nil and parms.lk == nil then
parms.opt_values = true
end
parms.table_align = parms.opt_table and 'right' or 'center'
end
if parms.table_align or parms.opt_sortable_on then
parms.need_table_or_sort = true
end
local disp_joins = text_code.disp_joins
local default_joins = disp_joins['b']
parms.join_between = default_joins[3] or '; '
local disp = parms.disp
if disp == nil then -- special case for the most common setting
parms.joins = default_joins
elseif disp == 'x' then
-- Later, parms.joins is set from the input parameters.
else
-- Old template does this.
local abbr = parms.abbr
if disp == 'slash' then
if abbr_entered == nil then
disp = 'slash-nbsp'
elseif abbr == 'in' or abbr == 'out' then
disp = 'slash-sp'
else
disp = 'slash-nosp'
end
elseif disp == 'sqbr' then
if abbr == 'on' then
disp = 'sqbr-nbsp'
else
disp = 'sqbr-sp'
end
end
parms.joins = disp_joins[disp] or default_joins
parms.join_between = parms.joins[3] or parms.join_between
parms.wantname = parms.joins.wantname
end
if (en_default and not parms.opt_lang_local and (parms[1] or ''):find('%d')) or parms.opt_lang_en then
from_en_table = nil
end
if en_default and from_en_table then
-- For hiwiki: localized symbol/name is defined with the US symbol/name field,
-- and is used if output uses localized numbers.
parms.opt_sp_us = true
end
return true
end
local function get_values(parms)
-- If successful, update parms and return true, v, i where
-- v = table of input values
-- i = index to next entry in parms after those processed here
-- or return false, t where t is an error message table.
local valinfo = collection() -- numbered table of input values
local range = collection() -- numbered table of range items (having, for example, 2 range items requires 3 input values)
local had_nocomma -- true if removed "nocomma" kludge from second parameter (like "tonocomma")
local parm2 = strip(parms[2])
if parm2 and parm2:sub(-7, -1) == 'nocomma' then
parms[2] = strip(parm2:sub(1, -8))
parms.opt_nocomma = true
had_nocomma = true
end
local function extractor(i)
-- If the parameter is not a value, try unpacking it as a range ("1-23" for "1 to 23").
-- However, "-1-2/3" is a negative fraction (-1⅔), so it must be extracted first.
-- Do not unpack a parameter if it is like "3-1/2" which is sometimes incorrectly
-- used instead of "3+1/2" (and which should not be interpreted as "3 to ½").
-- Unpacked items are inserted into the parms table.
-- The tail recursion allows combinations like "1x2 to 3x4".
local valstr = strip(parms[i]) -- trim so any '-' as a negative sign will be at start
local success, result = extract_number(parms, valstr, i > 1)
if not success and valstr and i < 20 then -- check i to limit abuse
local lhs, sep, rhs = valstr:match('^(%S+)%s+(%S+)%s+(%S.*)')
if lhs and not (sep == '-' and rhs:match('/')) then
if sep:find('%d') then
return success, result -- to reject {{convert|1 234 567|m}} with a decent message (en only)
end
parms[i] = rhs
table.insert(parms, i, sep)
table.insert(parms, i, lhs)
return extractor(i)
end
if not valstr:match('%-.*/') then
for _, sep in ipairs(text_code.ranges.words) do
local start, stop = valstr:find(sep, 2, true) -- start at 2 to skip any negative sign for range '-'
if start then
parms[i] = valstr:sub(stop + 1)
table.insert(parms, i, sep)
table.insert(parms, i, valstr:sub(1, start - 1))
return extractor(i)
end
end
end
end
return success, result
end
local i = 1
local is_change
while true do
local success, info = extractor(i) -- need to set parms.opt_nocomma before calling this
if not success then return false, info end
i = i + 1
if is_change then
info.is_change = true -- value is after "±" and so is a change (significant for range like {{convert|5|±|5|°C}})
is_change = nil
end
valinfo:add(info)
local range_item = get_range(strip(parms[i]))
if not range_item then
break
end
i = i + 1
range:add(range_item)
if type(range_item) == 'table' then
-- For range "x", if append unit to some values, append it to all.
parms.in_range_x = parms.in_range_x or range_item.in_range_x
parms.out_range_x = parms.out_range_x or range_item.out_range_x
parms.abbr_range_x = parms.abbr_range_x or range_item.abbr_range_x
is_change = range_item.is_range_change
end
end
if range.n > 0 then
if range.n > 30 then -- limit abuse, although 4 is a more likely upper limit
return false, { 'cvt_invalid_num' } -- misleading message but it will do
end
parms.range = range
elseif had_nocomma then
return false, { 'cvt_unknown', parm2 }
end
return true, valinfo, i
end
local function simple_get_values(parms)
-- If input is like "{{convert|valid_value|valid_unit|...}}",
-- return true, i, in_unit, in_unit_table
-- i = index in parms of what follows valid_unit, if anything.
-- The valid_value is not negative and does not use a fraction, and
-- no options requiring further processing of the input are used.
-- Otherwise, return nothing or return false, parm1 for caller to interpret.
-- Testing shows this function is successful for 96% of converts in articles,
-- and that on average it speeds up converts by 8%.
local clean = to_en(strip(parms[1] or ''), parms)
if parms.opt_ri or parms.opt_spell_in or #clean > 10 or not clean:match('^[0-9.]+$') then
return false, clean
end
local value = tonumber(clean)
if not value then return end
local info = {
value = value,
altvalue = value,
singular = (value == 1),
clean = clean,
show = with_separator(parms, clean),
}
local in_unit = strip(parms[2])
local success, in_unit_table = lookup(parms, in_unit, 'no_combination')
if not success then return end
in_unit_table.valinfo = { info }
return true, 3, in_unit, in_unit_table
end
local function wikidata_call(parms, operation, ...)
-- Return true, s where s is the result of a Wikidata operation,
-- or return false, t where t is an error message table.
local function worker(...)
wikidata_code = wikidata_code or require(wikidata_module)
wikidata_data = wikidata_data or mw.loadData(wikidata_data_module)
return wikidata_code[operation](wikidata_data, ...)
end
local success, status, result = pcall(worker, ...)
if success then
return status, result
end
if parms.opt_sortable_debug then
-- Use debug=yes to crash if an error while accessing Wikidata.
error('Error accessing Wikidata: ' .. status, 0)
end
return false, { 'cvt_wd_fail' }
end
local function get_parms(parms, args)
-- If successful, update parms and return true, unit where
-- parms is a table of all arguments passed to the template
-- converted to named arguments, and
-- unit is the input unit table;
-- or return false, t where t is an error message table.
-- For special processing (not a convert), can also return
-- true, wikitext where wikitext is the final result.
-- The returned input unit table may be for a fake unit using the specified
-- unit code as the symbol and name, and with bad_mcode = message code table.
-- MediaWiki removes leading and trailing whitespace from the values of
-- named arguments. However, the values of numbered arguments include any
-- whitespace entered in the template, and whitespace is used by some
-- parameters (example: the numbered parameters associated with "disp=x").
local kv_pairs = {} -- table of input key:value pairs where key is a name; needed because cannot iterate parms and add new fields to it
for k, v in pairs(args) do
if type(k) == 'number' or k == 'test' then -- parameter "test" is reserved for testing and is not translated
parms[k] = v
else
kv_pairs[k] = v
end
end
if parms.test == 'wikidata' then
local ulookup = function (ucode)
-- Use empty table for parms so it does not accumulate results when used repeatedly.
return lookup({}, ucode, 'no_combination')
end
return wikidata_call(parms, '_listunits', ulookup)
end
local success, msg = translate_parms(parms, kv_pairs)
if not success then return false, msg end
if parms.input then
success, msg = wikidata_call(parms, '_adjustparameters', parms, 1)
if not success then return false, msg end
end
local success, i, in_unit, in_unit_table = simple_get_values(parms)
if not success then
if type(i) == 'string' and i:match('^NNN+$') then
-- Some infoboxes have examples like {{convert|NNN|m}} (3 or more "N").
-- Output an empty string for these.
return false, { 'cvt_no_output' }
end
local valinfo
success, valinfo, i = get_values(parms)
if not success then return false, valinfo end
in_unit = strip(parms[i])
i = i + 1
success, in_unit_table = lookup(parms, in_unit, 'no_combination')
if not success then
in_unit = in_unit or ''
if parms.opt_ignore_error then -- display given unit code with no error (for use with {{val}})
in_unit_table = '' -- suppress error message and prevent processing of output unit
end
in_unit_table = setmetatable({
symbol = in_unit, name2 = in_unit, utype = in_unit,
scale = 1, default = '', defkey = '', linkey = '',
bad_mcode = in_unit_table }, unit_mt)
end
in_unit_table.valinfo = valinfo
end
if parms.test == 'msg' then
-- Am testing the messages produced when no output unit is specified, and
-- the input unit has a missing or invalid default.
-- Set two units for testing that.
-- LATER: Remove this code.
if in_unit == 'chain' then
in_unit_table.default = nil -- no default
elseif in_unit == 'rd' then
in_unit_table.default = "ft!X!m" -- an invalid expression
end
end
in_unit_table.inout = 'in' -- this is an input unit
if not parms.range then
local success, inext, composite_unit = get_composite(parms, i, in_unit_table)
if not success then return false, inext end
if composite_unit then
in_unit_table = composite_unit
i = inext
end
end
if in_unit_table.builtin == 'mach' then
-- As with old template, a number following Mach as the input unit is the altitude.
-- That is deprecated: should use altitude_ft=NUMBER or altitude_m=NUMBER.
local success, info
success = tonumber(parms[i]) -- this will often work and will give correct result for values like 2e4 without forcing output scientific notation
if success then
info = { value = success }
else
success, info = extract_number(parms, parms[i], false, true)
end
if success then
i = i + 1
in_unit_table.altitude = info.value
end
end
local word = strip(parms[i])
i = i + 1
local precision, is_bad_precision
local function set_precision(text)
local number, is_integer = get_number(text)
if number then
if is_integer then
precision = number
else
precision = text
is_bad_precision = true
end
return true -- text was used for precision, good or bad
end
end
if word and not set_precision(word) then
parms.out_unit = parms.out_unit or word
if set_precision(strip(parms[i])) then
i = i + 1
end
end
if parms.opt_adj_mid then
word = parms[i]
i = i + 1
if word then -- mid-text words
if word:sub(1, 1) == '-' then
parms.mid = word
else
parms.mid = ' ' .. word
end
end
end
if parms.opt_one_preunit then
parms[parms.opt_flip and 'preunit2' or 'preunit1'] = preunits(1, parms[i])
i = i + 1
end
if parms.disp == 'x' then
-- Following is reasonably compatible with the old template.
local first = parms[i] or ''
local second = parms[i+1] or ''
i = i + 2
if strip(first) == '' then -- user can enter ' ' rather than ' ' to avoid the default
first = ' [ ' .. first
second = ' ]' .. second
end
parms.joins = { first, second }
elseif parms.opt_two_preunits then
local p1, p2 = preunits(2, parms[i], parms[i+1])
i = i + 2
if parms.preunit1 then
-- To simplify documentation, allow unlikely use of adj=pre with disp=preunit
-- (however, an output unit must be specified with adj=pre and with disp=preunit).
parms.preunit1 = parms.preunit1 .. p1
parms.preunit2 = p2
else
parms.preunit1, parms.preunit2 = p1, p2
end
end
if precision == nil then
if set_precision(strip(parms[i])) then
i = i + 1
end
end
if is_bad_precision then
add_warning(parms, 1, 'cvt_bad_prec', precision)
else
parms.precision = precision
end
for j = i, i + 3 do
local parm = parms[j] -- warn if find a non-empty extraneous parameter
if parm and parm:match('%S') then
add_warning(parms, 1, 'cvt_unknown_option', parm)
break
end
end
return true, in_unit_table
end
local function record_default_precision(parms, out_current, precision)
-- If necessary, adjust parameters and return a possibly adjusted precision.
-- When converting a range of values where a default precision is required,
-- that default is calculated for each value because the result sometimes
-- depends on the precise input and output values. This function may cause
-- the entire convert process to be repeated in order to ensure that the
-- same default precision is used for each individual convert.
-- If that were not done, a range like 1000 to 1000.4 may give poor results
-- because the first output could be heavily rounded, while the second is not.
-- For range 1000.4 to 1000, this function can give the second convert the
-- same default precision that was used for the first.
if not parms.opt_round_each then
local maxdef = out_current.max_default_precision
if maxdef then
if maxdef < precision then
parms.do_convert_again = true
out_current.max_default_precision = precision
else
precision = out_current.max_default_precision
end
else
out_current.max_default_precision = precision
end
end
return precision
end
local function default_precision(parms, invalue, inclean, denominator, outvalue, in_current, out_current, extra)
-- Return a default value for precision (an integer like 2, 0, -2).
-- If denominator is not nil, it is the value of the denominator in inclean.
-- Code follows procedures used in old template.
local fudge = 1e-14 -- {{Order of magnitude}} adds this, so we do too
local prec, minprec, adjust
local subunit_ignore_trailing_zero
local subunit_more_precision -- kludge for "in" used in input like "|2|ft|6|in"
local composite = in_current.composite
if composite then
subunit_ignore_trailing_zero = true -- input "|2|st|10|lb" has precision 0, not -1
if composite[#composite].exception == 'subunit_more_precision' then
subunit_more_precision = true -- do not use standard precision with input like "|2|ft|6|in"
end
end
if denominator and denominator > 0 then
prec = math.max(log10(denominator), 1)
else
-- Count digits after decimal mark, handling cases like '12.345e6'.
local exponent
local integer, dot, decimals, expstr = inclean:match('^(%d*)(%.?)(%d*)(.*)')
local e = expstr:sub(1, 1)
if e == 'e' or e == 'E' then
exponent = tonumber(expstr:sub(2))
end
if dot == '' then
prec = subunit_ignore_trailing_zero and 0 or -integer:match('0*$'):len()
else
prec = #decimals
end
if exponent then
-- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5.
prec = prec - exponent
end
end
if in_current.istemperature and out_current.istemperature then
-- Converting between common temperatures (°C, °F, °R, K); not keVT.
-- Kelvin value can be almost zero, or small but negative due to precision problems.
-- Also, an input value like -300 C (below absolute zero) gives negative kelvins.
-- Calculate minimum precision from absolute value.
adjust = 0
local kelvin = abs((invalue - in_current.offset) * in_current.scale)
if kelvin < 1e-8 then -- assume nonzero due to input or calculation precision problem
minprec = 2
else
minprec = 2 - floor(log10(kelvin) + fudge) -- 3 sigfigs in kelvin
end
else
if invalue == 0 or outvalue <= 0 then
-- We are never called with a negative outvalue, but it might be zero.
-- This is special-cased to avoid calculation exceptions.
return record_default_precision(parms, out_current, 0)
end
if out_current.exception == 'integer_more_precision' and floor(invalue) == invalue then
-- With certain output units that sometimes give poor results
-- with default rounding, use more precision when the input
-- value is equal to an integer. An example of a poor result
-- is when input 50 gives a smaller output than input 49.5.
-- Experiment shows this helps, but it does not eliminate all
-- surprises because it is not clear whether "50" should be
-- interpreted as "from 45 to 55" or "from 49.5 to 50.5".
adjust = -log10(in_current.scale)
elseif subunit_more_precision then
-- Conversion like "{{convert|6|ft|1|in|cm}}" (where subunit is "in")
-- has a non-standard adjust value, to give more output precision.
adjust = log10(out_current.scale) + 2
else
adjust = log10(abs(invalue / outvalue))
end
adjust = adjust + log10(2)
-- Ensure that the output has at least two significant figures.
minprec = 1 - floor(log10(outvalue) + fudge)
end
if extra then
adjust = extra.adjust or adjust
minprec = extra.minprec or minprec
end
return record_default_precision(parms, out_current, math.max(floor(prec + adjust), minprec))
end
local function convert(parms, invalue, info, in_current, out_current)
-- Convert given input value from one unit to another.
-- Return output_value (a number) if a simple convert, or
-- return f, t where
-- f = true, t = table of information with results, or
-- f = false, t = error message table.
local inscale = in_current.scale
local outscale = out_current.scale
if not in_current.iscomplex and not out_current.iscomplex then
return invalue * (inscale / outscale) -- minimize overhead for most common case
end
if in_current.invert or out_current.invert then
-- Inverted units, such as inverse length, inverse time, or
-- fuel efficiency. Built-in units do not have invert set.
if (in_current.invert or 1) * (out_current.invert or 1) < 0 then
return 1 / (invalue * inscale * outscale)
end
return invalue * (inscale / outscale)
elseif in_current.offset then
-- Temperature (there are no built-ins for this type of unit).
if info.is_change then
return invalue * (inscale / outscale)
end
return (invalue - in_current.offset) * (inscale / outscale) + out_current.offset
else
-- Built-in unit.
local in_builtin = in_current.builtin
local out_builtin = out_current.builtin
if in_builtin and out_builtin then
if in_builtin == out_builtin then
return invalue
end
-- There are no cases (yet) where need to convert from one
-- built-in unit to another, so this should never occur.
return false, { 'cvt_bug_convert' }
end
if in_builtin == 'mach' or out_builtin == 'mach' then
-- Should check that only one altitude is given but am planning to remove
-- in_current.altitude (which can only occur when Mach is the input unit),
-- and out_current.altitude cannot occur.
local alt = parms.altitude_ft or in_current.altitude
if not alt and parms.altitude_m then
alt = parms.altitude_m / 0.3048 -- 1 ft = 0.3048 m
end
local spd = speed_of_sound(alt)
if in_builtin == 'mach' then
inscale = spd
return invalue * (inscale / outscale)
end
outscale = spd
local adjust = 0.1 / inscale
return true, {
outvalue = invalue * (inscale / outscale),
adjust = log10(adjust) + log10(2),
}
elseif in_builtin == 'hand' then
-- 1 hand = 4 inches; 1.2 hands = 6 inches.
-- Decimals of a hand are only defined for the first digit, and
-- the first fractional digit should be a number of inches (1, 2 or 3).
-- However, this code interprets the entire fractional part as the number
-- of inches / 10 (so 1.75 inches would be 0.175 hands).
-- A value like 12.3 hands is exactly 12*4 + 3 inches; base default precision on that.
local integer, fracpart = math.modf(invalue)
local inch_value = 4 * integer + 10 * fracpart -- equivalent number of inches
local factor = inscale / outscale
if factor == 4 then
-- Am converting to inches: show exact result, and use "inches" not "in" by default.
if parms.abbr_org == nil then
out_current.usename = true
end
local show = format('%g', abs(inch_value)) -- show and clean are unsigned
if not show:find('e', 1, true) then
return true, {
invalue = inch_value,
outvalue = inch_value,
clean = show,
show = show,
}
end
end
local outvalue = (integer + 2.5 * fracpart) * factor
local fracstr = info.clean:match('%.(.*)') or ''
local fmt
if fracstr == '' then
fmt = '%.0f'
else
fmt = '%.' .. format('%d', #fracstr - 1) .. 'f'
end
return true, {
invalue = inch_value,
clean = format(fmt, inch_value),
outvalue = outvalue,
minprec = 0,
}
end
end
return false, { 'cvt_bug_convert' } -- should never occur
end
local function user_style(parms, i)
-- Return text for a user-specified style for a table cell, or '' if none,
-- given i = 1 (input style) or 2 (output style).
local style = parms[(i == 1) and 'stylein' or 'styleout']
if style then
style = style:gsub('"', '')
if style ~= '' then
if style:sub(-1) ~= ';' then
style = style .. ';'
end
return style
end
end
return ''
end
local function make_table_or_sort(parms, invalue, info, in_current, scaled_top)
-- Set options to handle output for a table or a sort key, or both.
-- The text sort key is based on the value resulting from converting
-- the input to a fake base unit with scale = 1, and other properties
-- required for a conversion derived from the input unit.
-- For other modules, return the sort key in a hidden span element, and
-- the scaled value used to generate the sort key.
-- If scaled_top is set, it is the scaled value of the numerator of a per unit
-- to be combined with this unit (the denominator) to make the sort key.
-- Scaling only works with units that convert with a factor (not temperature).
local sortkey, scaled_value
if parms.opt_sortable_on then
local base = { -- a fake unit with enough fields for a valid convert
scale = 1,
invert = in_current.invert and 1,
iscomplex = in_current.iscomplex,
offset = in_current.offset and 0,
}
local outvalue, extra = convert(parms, invalue, info, in_current, base)
if extra then
outvalue = extra.outvalue
end
if in_current.istemperature then
-- Have converted to kelvin; assume numbers close to zero have a
-- rounding error and should be zero.
if abs(outvalue) < 1e-12 then
outvalue = 0
end
end
if scaled_top and outvalue ~= 0 then
outvalue = scaled_top / outvalue
end
scaled_value = outvalue
if not valid_number(outvalue) then
if outvalue < 0 then
sortkey = '1000000000000000000'
else
sortkey = '9000000000000000000'
end
elseif outvalue == 0 then
sortkey = '5000000000000000000'
else
local mag = floor(log10(abs(outvalue)) + 1e-14)
local prefix
if outvalue > 0 then
prefix = 7000 + mag
else
prefix = 2999 - mag
outvalue = outvalue + 10^(mag+1)
end
sortkey = format('%d', prefix) .. format('%015.0f', floor(outvalue * 10^(14-mag)))
end
end
local sortspan
if sortkey and not parms.table_align then
sortspan = parms.opt_sortable_debug and
'<span data-sort-value="' .. sortkey .. '♠"><span style="border:1px solid">' .. sortkey .. '♠</span></span>' or
'<span data-sort-value="' .. sortkey .. '♠"></span>'
parms.join_before = sortspan
end
if parms.table_align then
local sort
if sortkey then
sort = ' data-sort-value="' .. sortkey .. '"'
if parms.opt_sortable_debug then
parms.join_before = '<span style="border:1px solid">' .. sortkey .. '</span>'
end
else
sort = ''
end
local style = 'style="text-align:' .. parms.table_align .. ';'
local joins = {}
for i = 1, 2 do
joins[i] = (i == 1 and '' or '\n|') .. style .. user_style(parms, i) .. '"' .. sort .. '|'
end
parms.table_joins = joins
end
return sortspan, scaled_value
end
local cvt_to_hand
local function cvtround(parms, info, in_current, out_current)
-- Return true, t where t is a table with the conversion results; fields:
-- show = rounded, formatted string with the result of converting value in info,
-- using the rounding specified in parms.
-- singular = true if result (after rounding and ignoring any negative sign)
-- is "1", or like "1.00", or is a fraction with value < 1;
-- (and more fields shown below, and a calculated 'absvalue' field).
-- or return false, t where t is an error message table.
-- Input info.clean uses en digits (it has been translated, if necessary).
-- Output show uses en or non-en digits as appropriate, or can be spelled.
if out_current.builtin == 'hand' then
return cvt_to_hand(parms, info, in_current, out_current)
end
local invalue = in_current.builtin == 'hand' and info.altvalue or info.value
local outvalue, extra = convert(parms, invalue, info, in_current, out_current)
if parms.need_table_or_sort then
parms.need_table_or_sort = nil -- process using first input value only
make_table_or_sort(parms, invalue, info, in_current)
end
if extra then
if not outvalue then return false, extra end
invalue = extra.invalue or invalue
outvalue = extra.outvalue
end
if not valid_number(outvalue) then
return false, { 'cvt_invalid_num' }
end
local isnegative
if outvalue < 0 then
isnegative = true
outvalue = -outvalue
end
local precision, show, exponent
local denominator = out_current.frac
if denominator then
show = fraction_table(outvalue, denominator)
else
precision = parms.precision
if not precision then
if parms.sigfig then
show, exponent = make_sigfig(outvalue, parms.sigfig)
elseif parms.opt_round then
local n = parms.opt_round
if n == 0.5 then
local integer, fracpart = math.modf(floor(2 * outvalue + 0.5) / 2)
if fracpart == 0 then
show = format('%.0f', integer)
else
show = format('%.1f', integer + fracpart)
end
else
show = format('%.0f', floor((outvalue / n) + 0.5) * n)
end
elseif in_current.builtin == 'mach' then
local sigfig = info.clean:gsub('^[0.]+', ''):gsub('%.', ''):len() + 1
show, exponent = make_sigfig(outvalue, sigfig)
else
local inclean = info.clean
if extra then
inclean = extra.clean or inclean
show = extra.show
end
if not show then
precision = default_precision(parms, invalue, inclean, info.denominator, outvalue, in_current, out_current, extra)
end
end
end
end
if precision then
if precision >= 0 then
local fudge
if precision <= 8 then
-- Add a fudge to handle common cases of bad rounding due to inability
-- to precisely represent some values. This makes the following work:
-- {{convert|-100.1|C|K}} and {{convert|5555000|um|m|2}}.
-- Old template uses #expr round, which invokes PHP round().
-- LATER: Investigate how PHP round() works.
fudge = 2e-14
else
fudge = 0
end
local fmt = '%.' .. format('%d', precision) .. 'f'
local success
success, show = pcall(format, fmt, outvalue + fudge)
if not success then
return false, { 'cvt_big_prec', tostring(precision) }
end
else
precision = -precision -- #digits to zero (in addition to any digits after dot)
local shift = 10 ^ precision
show = format('%.0f', outvalue/shift)
if show ~= '0' then
exponent = #show + precision
end
end
end
local t = format_number(parms, show, exponent, isnegative)
if type(show) == 'string' then
-- Set singular using match because on some systems 0.99999999999999999 is 1.0.
if exponent then
t.singular = (exponent == 1 and show:match('^10*$'))
else
t.singular = (show == '1' or show:match('^1%.0*$'))
end
else
t.fraction_table = show
t.singular = (outvalue <= 1) -- cannot have 'fraction == 1', but if it were possible it would be singular
end
t.raw_absvalue = outvalue -- absolute value before rounding
return true, setmetatable(t, {
__index = function (self, key)
if key == 'absvalue' then
-- Calculate absolute value after rounding, if needed.
local clean, exponent = rawget(self, 'clean'), rawget(self, 'exponent')
local value = tonumber(clean) -- absolute value (any negative sign has been ignored)
if exponent then
value = value * 10^exponent
end
rawset(self, key, value)
return value
end
end })
end
function cvt_to_hand(parms, info, in_current, out_current)
-- Convert input to hands, inches.
-- Return true, t where t is a table with the conversion results;
-- or return false, t where t is an error message table.
if parms.abbr_org == nil then
out_current.usename = true -- default is to show name not symbol
end
local precision = parms.precision
local frac = out_current.frac
if not frac and precision and precision > 1 then
frac = (precision == 2) and 2 or 4
end
local out_next = out_current.out_next
if out_next then
-- Use magic knowledge to determine whether the next unit is inches without requiring i18n.
-- The following ensures that when the output combination "hand in" is used, the inches
-- value is rounded to match the hands value. Also, displaying say "61½" instead of 61.5
-- is better as 61.5 implies the value is not 61.4.
if out_next.exception == 'subunit_more_precision' then
out_next.frac = frac
end
end
-- Convert to inches; calculate hands from that.
local dummy_unit_table = { scale = out_current.scale / 4, frac = frac }
local success, outinfo = cvtround(parms, info, in_current, dummy_unit_table)
if not success then return false, outinfo end
local tfrac = outinfo.fraction_table
local inches = outinfo.raw_absvalue
if tfrac then
inches = floor(inches) -- integer part only; fraction added later
else
inches = floor(inches + 0.5) -- a hands measurement never shows decimals of an inch
end
local hands, inches = divide(inches, 4)
outinfo.absvalue = hands + inches/4 -- supposed to be the absolute rounded value, but this is close enough
local inchstr = tostring(inches) -- '0', '1', '2' or '3'
if precision and precision <= 0 then -- using negative or 0 for precision rounds to nearest hand
hands = floor(outinfo.raw_absvalue/4 + 0.5)
inchstr = ''
elseif tfrac then
-- Always show an integer before fraction (like "15.0½") because "15½" means 15-and-a-half hands.
inchstr = numdot .. format_fraction(parms, 'out', false, inchstr, tfrac.numstr, tfrac.denstr)
else
inchstr = numdot .. from_en(inchstr)
end
outinfo.show = outinfo.sign .. with_separator(parms, format('%.0f', hands)) .. inchstr
return true, outinfo
end
local function evaluate_condition(value, condition)
-- Return true or false from applying a conditional expression to value,
-- or throw an error if invalid.
-- A very limited set of expressions is supported:
-- v < 9
-- v * 9 < 9
-- where
-- 'v' is replaced with value
-- 9 is any number (as defined by Lua tonumber)
-- only en digits are accepted
-- '<' can also be '<=' or '>' or '>='
-- In addition, the following form is supported:
-- LHS and RHS
-- where
-- LHS, RHS = any of above expressions.
local function compare(value, text)
local arithop, factor, compop, limit = text:match('^%s*v%s*([*]?)(.-)([<>]=?)(.*)$')
if arithop == nil then
error('Invalid default expression', 0)
elseif arithop == '*' then
factor = tonumber(factor)
if factor == nil then
error('Invalid default expression', 0)
end
value = value * factor
end
limit = tonumber(limit)
if limit == nil then
error('Invalid default expression', 0)
end
if compop == '<' then
return value < limit
elseif compop == '<=' then
return value <= limit
elseif compop == '>' then
return value > limit
elseif compop == '>=' then
return value >= limit
end
error('Invalid default expression', 0) -- should not occur
end
local lhs, rhs = condition:match('^(.-%W)and(%W.*)')
if lhs == nil then
return compare(value, condition)
end
return compare(value, lhs) and compare(value, rhs)
end
local function get_default(value, unit_table)
-- Return true, s where s = name of unit's default output unit,
-- or return false, t where t is an error message table.
-- Some units have a default that depends on the input value
-- (the first value if a range of values is used).
-- If '!' is in the default, the first bang-delimited field is an
-- expression that uses 'v' to represent the input value.
-- Example: 'v < 120 ! small ! big ! suffix' (suffix is optional)
-- evaluates 'v < 120' as a boolean with result
-- 'smallsuffix' if (value < 120), or 'bigsuffix' otherwise.
-- Input must use en digits and '.' decimal mark.
local default = data_code.default_exceptions[unit_table.defkey or unit_table.symbol] or unit_table.default
if not default then
local per = unit_table.per
if per then
local function a_default(v, u)
local success, ucode = get_default(v, u)
if not success then
return '?' -- an unlikely error has occurred; will cause lookup of default to fail
end
-- Attempt to use only the first unit if a combination or output multiple.
-- This is not bulletproof but should work for most cases.
-- Where it does not work, the convert will need to specify the wanted output unit.
local t = all_units[ucode]
if t then
local combo = t.combination
if combo then
-- For a multiple like ftin, the "first" unit (ft) is last in the combination.
local i = t.multiple and table_len(combo) or 1
ucode = combo[i]
end
else
-- Try for an automatically generated combination.
local item = ucode:match('^(.-)%+') or ucode:match('^(%S+)%s')
if all_units[item] then
return item
end
end
return ucode
end
local unit1, unit2 = per[1], per[2]
local def1 = (unit1 and a_default(value, unit1) or unit_table.vprefix or '')
local def2 = a_default(1, unit2) -- 1 because per unit of denominator
return true, def1 .. '/' .. def2
end
return false, { 'cvt_no_default', unit_table.symbol }
end
if default:find('!', 1, true) == nil then
return true, default
end
local t = split(default, '!')
if #t == 3 or #t == 4 then
local success, result = pcall(evaluate_condition, value, t[1])
if success then
default = result and t[2] or t[3]
if #t == 4 then
default = default .. t[4]
end
return true, default
end
end
return false, { 'cvt_bad_default', unit_table.symbol }
end
local linked_pages -- to record linked pages so will not link to the same page more than once
local function unlink(unit_table)
-- Forget that the given unit has previously been linked (if it has).
-- That is needed when processing a range of inputs or outputs when an id
-- for the first range value may have been evaluated, but only an id for
-- the last value is displayed, and that id may need to be linked.
linked_pages[unit_table.unitcode or unit_table] = nil
end
local function make_link(link, id, unit_table)
-- Return wikilink "[[link|id]]", possibly abbreviated as in examples:
-- [[Mile|mile]] --> [[mile]]
-- [[Mile|miles]] --> [[mile]]s
-- However, just id is returned if:
-- * no link given (so caller does not need to check if a link was defined); or
-- * link has previously been used during the current convert (to avoid overlinking).
local link_key
if unit_table then
link_key = unit_table.unitcode or unit_table
else
link_key = link
end
if not link or link == '' or linked_pages[link_key] then
return id
end
linked_pages[link_key] = true
-- Following only works for language en, but it should be safe on other wikis,
-- and overhead of doing it generally does not seem worthwhile.
local l = link:sub(1, 1):lower() .. link:sub(2)
if link == id or l == id then
return '[[' .. id .. ']]'
elseif link .. 's' == id or l .. 's' == id then
return '[[' .. id:sub(1, -2) .. ']]s'
else
return '[[' .. link .. '|' .. id .. ']]'
end
end
local function variable_name(clean, unit_table)
-- For slwiki, a unit name depends on the value.
-- Parameter clean is the unsigned rounded value in en digits, as a string.
-- Value Source Example for "m"
-- integer 1: name1 meter (also is the name of the unit)
-- integer 2: var{1} metra
-- integer 3 and 4: var{2} metri
-- integer else: var{3} metrov (0 and 5 or more)
-- real/fraction: var{4} metra
-- var{i} means the i'th field in unit_table.varname if it exists and has
-- an i'th field, otherwise name2.
-- Fields are separated with "!" and are not empty.
-- A field for a unit using an SI prefix has the prefix name inserted,
-- replacing '#' if found, or before the field otherwise.
local vname
if clean == '1' then
vname = unit_table.name1
elseif unit_table.varname then
local i
if clean == '2' then
i = 1
elseif clean == '3' or clean == '4' then
i = 2
elseif clean:find('.', 1, true) then
i = 4
else
i = 3
end
if i > 1 and varname == 'pl' then
i = i - 1
end
vname = split(unit_table.varname, '!')[i]
end
if vname then
local si_name = rawget(unit_table, 'si_name') or ''
local pos = vname:find('#', 1, true)
if pos then
vname = vname:sub(1, pos - 1) .. si_name .. vname:sub(pos + 1)
else
vname = si_name .. vname
end
return vname
end
return unit_table.name2
end
local function linked_id(parms, unit_table, key_id, want_link, clean)
-- Return final unit id (symbol or name), optionally with a wikilink,
-- and update unit_table.sep if required.
-- key_id is one of: 'symbol', 'sym_us', 'name1', 'name1_us', 'name2', 'name2_us'.
local abbr_on = (key_id == 'symbol' or key_id == 'sym_us')
if abbr_on and want_link then
local symlink = rawget(unit_table, 'symlink')
if symlink then
return symlink -- for exceptions that have the linked symbol built-in
end
end
local multiplier = rawget(unit_table, 'multiplier')
local per = unit_table.per
if per then
local paren1, paren2 = '', '' -- possible parentheses around bottom unit
local unit1 = per[1] -- top unit_table, or nil
local unit2 = per[2] -- bottom unit_table
if abbr_on then
if not unit1 then
unit_table.sep = '' -- no separator in "$2/acre"
end
if not want_link then
local symbol = unit_table.symbol_raw
if symbol then
return symbol -- for exceptions that have the symbol built-in
end
end
if (unit2.symbol):find('⋅', 1, true) then
paren1, paren2 = '(', ')'
end
end
local key_id2 -- unit2 is always singular
if key_id == 'name2' then
key_id2 = 'name1'
elseif key_id == 'name2_us' then
key_id2 = 'name1_us'
else
key_id2 = key_id
end
local result
if abbr_on then
result = '/'
elseif omitsep then
result = per_word
elseif unit1 then
result = ' ' .. per_word .. ' '
else
result = per_word .. ' '
end
if want_link and unit_table.link then
if abbr_on or not varname then
result = (unit1 and linked_id(parms, unit1, key_id, false, clean) or '') .. result .. linked_id(parms, unit2, key_id2, false, '1')
else
result = (unit1 and variable_name(clean, unit1) or '') .. result .. variable_name('1', unit2)
end
if omit_separator(result) then
unit_table.sep = ''
end
return make_link(unit_table.link, result, unit_table)
end
if unit1 then
result = linked_id(parms, unit1, key_id, want_link, clean) .. result
if unit1.sep then
unit_table.sep = unit1.sep
end
elseif omitsep then
unit_table.sep = ''
end
return result .. paren1 .. linked_id(parms, unit2, key_id2, want_link, '1') .. paren2
end
if multiplier then
-- A multiplier (like "100" in "100km") forces the unit to be plural.
multiplier = from_en(multiplier)
if not omitsep then
multiplier = multiplier .. (abbr_on and ' ' or ' ')
end
if not abbr_on then
if key_id == 'name1' then
key_id = 'name2'
elseif key_id == 'name1_us' then
key_id = 'name2_us'
end
end
else
multiplier = ''
end
local id = unit_table.fixed_name or ((varname and not abbr_on) and variable_name(clean, unit_table) or unit_table[key_id])
if omit_separator(id) then
unit_table.sep = ''
end
if want_link then
local link = data_code.link_exceptions[unit_table.linkey or unit_table.symbol] or unit_table.link
if link then
local before = ''
local i = unit_table.customary
if i == 1 and parms.opt_sp_us then
i = 2 -- show "U.S." not "US"
end
if i == 3 and abbr_on then
i = 4 -- abbreviate "imperial" to "imp"
end
local customary = text_code.customary_units[i]
if customary then
-- LATER: This works for language en only, but it's esoteric so ignore for now.
local pertext
if id:sub(1, 1) == '/' then
-- Want unit "/USgal" to display as "/U.S. gal", not "U.S. /gal".
pertext = '/'
id = id:sub(2)
elseif id:sub(1, 4) == 'per ' then
-- Similarly want "per U.S. gallon", not "U.S. per gallon" (but in practice this is unlikely to be used).
pertext = 'per '
id = id:sub(5)
else
pertext = ''
end
-- Omit any "US"/"U.S."/"imp"/"imperial" from start of id since that will be inserted.
local removes = (i < 3) and { 'US ', 'US ', 'U.S. ', 'U.S. ' } or { 'imp ', 'imp ', 'imperial ' }
for _, prefix in ipairs(removes) do
local plen = #prefix
if id:sub(1, plen) == prefix then
id = id:sub(plen + 1)
break
end
end
before = pertext .. make_link(customary.link, customary[1]) .. ' '
end
id = before .. make_link(link, id, unit_table)
end
end
return multiplier .. id
end
local function make_id(parms, which, unit_table)
-- Return id, f where
-- id = unit name or symbol, possibly modified
-- f = true if id is a name, or false if id is a symbol
-- using the value for index 'which', and for 'in' or 'out' (unit_table.inout).
-- Result is '' if no symbol/name is to be used.
-- In addition, set unit_table.sep = ' ' or ' ' or ''
-- (the separator that caller will normally insert before the id).
if parms.opt_values then
unit_table.sep = ''
return ''
end
local inout = unit_table.inout
local info = unit_table.valinfo[which]
local abbr_org = parms.abbr_org
local adjectival = parms.opt_adjectival
local lk = parms.lk
local want_link = (lk == 'on' or lk == inout)
local usename = unit_table.usename
local singular = info.singular
local want_name
if usename then
want_name = true
else
if abbr_org == nil then
if parms.wantname then
want_name = true
end
if unit_table.usesymbol then
want_name = false
end
end
if want_name == nil then
local abbr = parms.abbr
if abbr == 'on' or abbr == inout or (abbr == 'mos' and inout == 'out') then
want_name = false
else
want_name = true
end
end
end
local key
if want_name then
if lk == nil and unit_table.builtin == 'hand' then
want_link = true
end
if parms.opt_use_nbsp then
unit_table.sep = ' '
else
unit_table.sep = ' '
end
if parms.opt_singular then
local value
if inout == 'in' then
value = info.value
else
value = info.absvalue
end
if value then -- some unusual units do not always set value field
value = abs(value)
singular = (0 < value and value < 1.0001)
end
end
if unit_table.engscale then
-- engscale: so "|1|e3kg" gives "1 thousand kilograms" (plural)
singular = false
end
key = (adjectival or singular) and 'name1' or 'name2'
if parms.opt_sp_us then
key = key .. '_us'
end
else
if unit_table.builtin == 'hand' then
if parms.opt_hand_hh then
unit_table.symbol = 'hh' -- LATER: might want i18n applied to this
end
end
unit_table.sep = ' '
key = parms.opt_sp_us and 'sym_us' or 'symbol'
end
return linked_id(parms, unit_table, key, want_link, info.clean), want_name
end
local function decorate_value(parms, unit_table, which, number_word)
-- If needed, update unit_table so values will be shown with extra information.
-- For consistency with the old template (but different from fmtpower),
-- the style to display powers of 10 includes "display:none" to allow some
-- browsers to copy, for example, "10³" as "10^3", rather than as "103".
local info
local engscale = unit_table.engscale
local prefix = unit_table.vprefix
if engscale or prefix then
info = unit_table.valinfo[which]
if info.decorated then
return -- do not redecorate if repeating convert
end
info.decorated = true
if engscale then
local inout = unit_table.inout
local abbr = parms.abbr
if (abbr == 'on' or abbr == inout) and not parms.number_word then
info.show = info.show ..
'<span style="margin-left:0.2em">×<span style="margin-left:0.1em">' ..
from_en('10') ..
'</span></span><s style="display:none">^</s><sup>' ..
from_en(tostring(engscale.exponent)) .. '</sup>'
elseif number_word then
local number_id
local lk = parms.lk
if lk == 'on' or lk == inout then
number_id = make_link(engscale.link, engscale[1])
else
number_id = engscale[1]
end
-- WP:NUMERAL recommends " " in values like "12 million".
info.show = info.show .. (parms.opt_adjectival and '-' or ' ') .. number_id
end
end
if prefix then
info.show = prefix .. info.show
end
end
end
local function process_input(parms, in_current)
-- Processing required once per conversion.
-- Return block of text to represent input (value/unit).
if parms.opt_output_only or parms.opt_output_number_only or parms.opt_output_unit_only then
parms.joins = { '', '' }
return ''
end
local first_unit
local composite = in_current.composite -- nil or table of units
if composite then
first_unit = composite[1]
else
first_unit = in_current
end
local id1, want_name = make_id(parms, 1, first_unit)
local sep = first_unit.sep -- separator between value and unit, set by make_id
local preunit = parms.preunit1
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_input_unit_only then
parms.joins = { '', '' }
if composite then
local parts = { id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, (make_id(parms, 1, unit)))
end
end
id1 = table.concat(parts, ' ')
end
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if parms.opt_also_symbol and not composite and not parms.opt_flip then
local join1 = parms.joins[1]
if join1 == ' (' or join1 == ' [' then
parms.joins = { ' [' .. first_unit[parms.opt_sp_us and 'sym_us' or 'symbol'] .. ']' .. join1 , parms.joins[2] }
end
end
if in_current.builtin == 'mach' and first_unit.sep ~= '' then -- '' means omitsep with non-enwiki name
local prefix = id1 .. ' '
local range = parms.range
local valinfo = first_unit.valinfo
local result = prefix .. valinfo[1].show
if range then
-- For simplicity and because more not needed, handle one range item only.
local prefix2 = make_id(parms, 2, first_unit) .. ' '
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in', {spaced=true})
end
return preunit .. result
end
if composite then
-- Simplify: assume there is no range, and no decoration.
local mid = (not parms.opt_flip) and parms.mid or ''
local sep1 = ' '
local sep2 = ' '
if parms.opt_adjectival and want_name then
sep1 = '-'
sep2 = '-'
end
if omitsep and sep == '' then
-- Testing the id of the most significant unit should be sufficient.
sep1 = ''
sep2 = ''
end
local parts = { first_unit.valinfo[1].show .. sep1 .. id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, unit.valinfo[1].show .. sep1 .. (make_id(parms, 1, unit)))
end
end
return table.concat(parts, sep2) .. mid
end
local add_unit = (parms.abbr == 'mos') or
parms[parms.opt_flip and 'out_range_x' or 'in_range_x'] or
(not want_name and parms.abbr_range_x)
local range = parms.range
if range and not add_unit then
unlink(first_unit)
end
local id = range and make_id(parms, range.n + 1, first_unit) or id1
local extra, was_hyphenated = hyphenated_maybe(parms, want_name, sep, id, 'in')
if was_hyphenated then
add_unit = false
end
local result
local valinfo = first_unit.valinfo
if range then
for i = 0, range.n do
local number_word
if i == range.n then
add_unit = false
number_word = true
end
decorate_value(parms, first_unit, i+1, number_word)
local show = valinfo[i+1].show
if add_unit then
show = show .. first_unit.sep .. (i == 0 and id1 or make_id(parms, i+1, first_unit))
end
if i == 0 then
result = show
else
result = range_text(range[i], want_name, parms, result, show, 'in')
end
end
else
decorate_value(parms, first_unit, 1, true)
result = valinfo[1].show
end
return result .. preunit .. extra
end
local function process_one_output(parms, out_current)
-- Processing required for each output unit.
-- Return block of text to represent output (value/unit).
local inout = out_current.inout -- normally 'out' but can be 'in' for order=out
local id1, want_name = make_id(parms, 1, out_current)
local sep = out_current.sep -- set by make_id
local preunit = parms.preunit2
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_output_unit_only then
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if out_current.builtin == 'mach' and out_current.sep ~= '' then -- '' means omitsep with non-enwiki name
local prefix = id1 .. ' '
local range = parms.range
local valinfo = out_current.valinfo
local result = prefix .. valinfo[1].show
if range then
-- For simplicity and because more not needed, handle one range item only.
result = range_text(range[1], want_name, parms, result, prefix .. valinfo[2].show, inout, {spaced=true})
end
return preunit .. result
end
local add_unit = (parms[parms.opt_flip and 'in_range_x' or 'out_range_x'] or
(not want_name and parms.abbr_range_x)) and
not parms.opt_output_number_only
local range = parms.range
if range and not add_unit then
unlink(out_current)
end
local id = range and make_id(parms, range.n + 1, out_current) or id1
local extra, was_hyphenated = hyphenated_maybe(parms, want_name, sep, id, inout)
if was_hyphenated then
add_unit = false
end
local result
local valinfo = out_current.valinfo
if range then
for i = 0, range.n do
local number_word
if i == range.n then
add_unit = false
number_word = true
end
decorate_value(parms, out_current, i+1, number_word)
local show = valinfo[i+1].show
if add_unit then
show = show .. out_current.sep .. (i == 0 and id1 or make_id(parms, i+1, out_current))
end
if i == 0 then
result = show
else
result = range_text(range[i], want_name, parms, result, show, inout)
end
end
else
decorate_value(parms, out_current, 1, true)
result = valinfo[1].show
end
if parms.opt_output_number_only then
return result
end
return result .. preunit .. extra
end
local function make_output_single(parms, in_unit_table, out_unit_table)
-- Return true, item where item = wikitext of the conversion result
-- for a single output (which is not a combination or a multiple);
-- or return false, t where t is an error message table.
if parms.opt_order_out and in_unit_table.unitcode == out_unit_table.unitcode then
out_unit_table.valinfo = in_unit_table.valinfo
else
out_unit_table.valinfo = collection()
for _, v in ipairs(in_unit_table.valinfo) do
local success, info = cvtround(parms, v, in_unit_table, out_unit_table)
if not success then return false, info end
out_unit_table.valinfo:add(info)
end
end
return true, process_one_output(parms, out_unit_table)
end
local function make_output_multiple(parms, in_unit_table, out_unit_table)
-- Return true, item where item = wikitext of the conversion result
-- for an output which is a multiple (like 'ftin');
-- or return false, t where t is an error message table.
local inout = out_unit_table.inout -- normally 'out' but can be 'in' for order=out
local multiple = out_unit_table.multiple -- table of scaling factors (will not be nil)
local combos = out_unit_table.combination -- table of unit tables (will not be nil)
local abbr = parms.abbr
local abbr_org = parms.abbr_org
local disp = parms.disp
local want_name = (abbr_org == nil and (disp == 'or' or disp == 'slash')) or
not (abbr == 'on' or abbr == inout or abbr == 'mos')
local want_link = (parms.lk == 'on' or parms.lk == inout)
local mid = parms.opt_flip and parms.mid or ''
local sep1 = ' '
local sep2 = ' '
if parms.opt_adjectival and want_name then
sep1 = '-'
sep2 = '-'
end
local do_spell = parms.opt_spell_out
parms.opt_spell_out = nil -- so the call to cvtround does not spell the value
local function make_result(info, isfirst)
local fmt, outvalue, sign
local results = {}
for i = 1, #combos do
local tfrac, thisvalue, strforce
local out_current = combos[i]
out_current.inout = inout
local scale = multiple[i]
if i == 1 then -- least significant unit ('in' from 'ftin')
local decimals
out_current.frac = out_unit_table.frac
local success, outinfo = cvtround(parms, info, in_unit_table, out_current)
if not success then return false, outinfo end
if isfirst then
out_unit_table.valinfo = { outinfo } -- in case output value of first least significant unit is needed
end
sign = outinfo.sign
tfrac = outinfo.fraction_table
if outinfo.is_scientific then
strforce = outinfo.show
decimals = ''
elseif tfrac then
decimals = ''
else
local show = outinfo.show -- number as a string in local language
local p1, p2 = show:find(numdot, 1, true)
decimals = p1 and show:sub(p2 + 1) or '' -- text after numdot, if any
end
fmt = '%.' .. ulen(decimals) .. 'f' -- to reproduce precision
if decimals == '' then
if tfrac then
outvalue = floor(outinfo.raw_absvalue) -- integer part only; fraction added later
else
outvalue = floor(outinfo.raw_absvalue + 0.5) -- keep all integer digits of least significant unit
end
else
outvalue = outinfo.absvalue
end
end
if scale then
outvalue, thisvalue = divide(outvalue, scale)
else
thisvalue = outvalue
end
local id
if want_name then
if varname then
local clean
if strforce or tfrac then
clean = '.1' -- dummy value to force name for floating point
else
clean = format(fmt, thisvalue)
end
id = variable_name(clean, out_current)
else
local key = 'name2'
if parms.opt_adjectival then
key = 'name1'
elseif tfrac then
if thisvalue == 0 then
key = 'name1'
end
elseif parms.opt_singular then
if 0 < thisvalue and thisvalue < 1.0001 then
key = 'name1'
end
else
if thisvalue == 1 then
key = 'name1'
end
end
id = out_current[key]
end
else
id = out_current['symbol']
end
if i == 1 and omit_separator(id) then
-- Testing the id of the least significant unit should be sufficient.
sep1 = ''
sep2 = ''
end
if want_link then
local link = out_current.link
if link then
id = make_link(link, id, out_current)
end
end
local strval
local spell_inout = (i == #combos or outvalue == 0) and inout or '' -- trick so the last value processed (first displayed) has uppercase, if requested
if strforce and outvalue == 0 then
sign = '' -- any sign is in strforce
strval = strforce -- show small values in scientific notation; will only use least significant unit
elseif tfrac then
local wholestr = (thisvalue > 0) and tostring(thisvalue) or nil
strval = format_fraction(parms, spell_inout, false, wholestr, tfrac.numstr, tfrac.denstr, do_spell)
else
strval = (thisvalue == 0) and from_en('0') or with_separator(parms, format(fmt, thisvalue))
if do_spell then
strval = spell_number(parms, spell_inout, strval) or strval
end
end
table.insert(results, strval .. sep1 .. id)
if outvalue == 0 then
break
end
fmt = '%.0f' -- only least significant unit can have a non-integral value
end
local reversed, count = {}, #results
for i = 1, count do
reversed[i] = results[count + 1 - i]
end
return true, sign .. table.concat(reversed, sep2)
end
local valinfo = in_unit_table.valinfo
local success, result = make_result(valinfo[1], true)
if not success then return false, result end
local range = parms.range
if range then
for i = 1, range.n do
local success, result2 = make_result(valinfo[i+1])
if not success then return false, result2 end
result = range_text(range[i], want_name, parms, result, result2, inout, {spaced=true})
end
end
return true, result .. mid
end
local function process(parms, in_unit_table, out_unit_table)
-- Return true, s, outunit where s = final wikitext result,
-- or return false, t where t is an error message table.
linked_pages = {}
local success, bad_output
local bad_input_mcode = in_unit_table.bad_mcode -- nil if input unit is a valid convert unit
local out_unit = parms.out_unit
if out_unit == nil or out_unit == '' or type(out_unit) == 'function' then
if bad_input_mcode or parms.opt_input_unit_only then
bad_output = ''
else
local getdef = type(out_unit) == 'function' and out_unit or get_default
success, out_unit = getdef(in_unit_table.valinfo[1].value, in_unit_table)
parms.out_unit = out_unit
if not success then
bad_output = out_unit
end
end
end
if not bad_output and not out_unit_table then
success, out_unit_table = lookup(parms, out_unit, 'any_combination')
if success then
local mismatch = check_mismatch(in_unit_table, out_unit_table)
if mismatch then
bad_output = mismatch
end
else
bad_output = out_unit_table
end
end
local lhs, rhs
local flipped = parms.opt_flip and not bad_input_mcode
if bad_output then
rhs = (bad_output == '') and '' or message(parms, bad_output)
elseif parms.opt_input_unit_only then
rhs = ''
else
local combos -- nil (for 'ft' or 'ftin'), or table of unit tables (for 'm ft')
if not out_unit_table.multiple then -- nil/false ('ft' or 'm ft'), or table of factors ('ftin')
combos = out_unit_table.combination
end
local frac = parms.frac -- nil or denominator of fraction for output values
if frac then
-- Apply fraction to the unit (if only one), or to non-SI units (if a combination),
-- except that if a precision is also specified, the fraction only applies to
-- the hand unit; that allows the following result:
-- {{convert|156|cm|in hand|1|frac=2}} → 156 centimetres (61.4 in; 15.1½ hands)
-- However, the following is handled elsewhere as a special case:
-- {{convert|156|cm|hand in|1|frac=2}} → 156 centimetres (15.1½ hands; 61½ in)
if combos then
local precision = parms.precision
for _, unit in ipairs(combos) do
if unit.builtin == 'hand' or (not precision and not unit.prefixes) then
unit.frac = frac
end
end
else
out_unit_table.frac = frac
end
end
local outputs = {}
local imax = combos and #combos or 1 -- 1 (single unit) or number of unit tables
if imax == 1 then
parms.opt_order_out = nil -- only useful with an output combination
end
if not flipped and not parms.opt_order_out then
-- Process left side first so any duplicate links (from lk=on) are suppressed
-- on right. Example: {{convert|28|e9pc|e9ly|abbr=off|lk=on}}
lhs = process_input(parms, in_unit_table)
end
for i = 1, imax do
local success, item
local out_current = combos and combos[i] or out_unit_table
out_current.inout = 'out'
if i == 1 then
if imax > 1 and out_current.builtin == 'hand' then
out_current.out_next = combos[2] -- built-in hand can influence next unit in a combination
end
if parms.opt_order_out then
out_current.inout = 'in'
end
end
if out_current.multiple then
success, item = make_output_multiple(parms, in_unit_table, out_current)
else
success, item = make_output_single(parms, in_unit_table, out_current)
end
if not success then return false, item end
outputs[i] = item
end
if parms.opt_order_out then
lhs = outputs[1]
table.remove(outputs, 1)
end
local sep = parms.table_joins and parms.table_joins[2] or parms.join_between
rhs = table.concat(outputs, sep)
end
if flipped or not lhs then
local input = process_input(parms, in_unit_table)
if flipped then
lhs = rhs
rhs = input
else
lhs = input
end
end
if parms.join_before then
lhs = parms.join_before .. lhs
end
local wikitext
if bad_input_mcode then
if bad_input_mcode == '' then
wikitext = lhs
else
wikitext = lhs .. message(parms, bad_input_mcode)
end
elseif parms.table_joins then
wikitext = parms.table_joins[1] .. lhs .. parms.table_joins[2] .. rhs
else
wikitext = lhs .. parms.joins[1] .. rhs .. parms.joins[2]
end
if parms.warnings and not bad_input_mcode then
wikitext = wikitext .. parms.warnings
end
return true, get_styles(parms) .. wikitext, out_unit_table
end
local function main_convert(frame)
-- Do convert, and if needed, do it again with higher default precision.
local parms = { frame = frame } -- will hold template arguments, after translation
set_config(frame.args)
local success, result = get_parms(parms, frame:getParent().args)
if success then
if type(result) ~= 'table' then
return tostring(result)
end
local in_unit_table = result
local out_unit_table
for _ = 1, 2 do -- use counter so cannot get stuck repeating convert
success, result, out_unit_table = process(parms, in_unit_table, out_unit_table)
if success and parms.do_convert_again then
parms.do_convert_again = false
else
break
end
end
end
-- If input=x gives a problem, the result should be just the user input
-- (if x is a property like P123 it has been replaced with '').
-- An unknown input unit would display the input and an error message
-- with success == true at this point.
-- Also, can have success == false with a message that outputs an empty string.
if parms.input_text then
if success and not parms.have_problem then
return result
end
local cat
if parms.tracking then
-- Add a tracking category using the given text as the category sort key.
-- There is currently only one type of tracking, but in principle multiple
-- items could be tracked, using different sort keys for convenience.
cat = wanted_category('tracking', parms.tracking)
end
return parms.input_text .. (cat or '')
end
return success and result or message(parms, result)
end
local function _unit(unitcode, options)
-- Helper function for Module:Val to look up a unit.
-- Parameter unitcode must be a string to identify the wanted unit.
-- Parameter options must be nil or a table with optional fields:
-- value = number (for sort key; default value is 1)
-- scaled_top = nil for a normal unit, or a number for a unit which is
-- the denominator of a per unit (for sort key)
-- si = { 'symbol', 'link' }
-- (a table with two strings) to make an SI unit
-- that will be used for the look up
-- link = true if result should be [[linked]]
-- sort = 'on' or 'debug' if result should include a sort key in a
-- span element ('debug' makes the key visible)
-- name = true for the name of the unit instead of the symbol
-- us = true for the US spelling of the unit, if any
-- Return nil if unitcode is not a non-empty string.
-- Otherwise return a table with fields:
-- text = requested symbol or name of unit, optionally linked
-- scaled_value = input value adjusted by unit scale; used for sort key
-- sortspan = span element with sort key like that provided by {{ntsh}},
-- calculated from the result of converting value
-- to a base unit with scale 1.
-- unknown = true if the unitcode was not known
unitcode = strip(unitcode)
if unitcode == nil or unitcode == '' then
return nil
end
set_config({})
linked_pages = {}
options = options or {}
local parms = {
abbr = options.name and 'off' or 'on',
lk = options.link and 'on' or nil,
opt_sp_us = options.us and true or nil,
opt_ignore_error = true, -- do not add pages using this function to 'what links here' for Module:Convert/extra
opt_sortable_on = options.sort == 'on' or options.sort == 'debug',
opt_sortable_debug = options.sort == 'debug',
}
if options.si then
-- Make a dummy table of units (just one unit) for lookup to use.
-- This makes lookup recognize any SI prefix in the unitcode.
local symbol = options.si[1] or '?'
parms.unittable = { [symbol] = {
_name1 = symbol,
_name2 = symbol,
_symbol = symbol,
utype = symbol,
scale = symbol == 'g' and 0.001 or 1,
prefixes = 1,
default = symbol,
link = options.si[2],
}}
end
local success, unit_table = lookup(parms, unitcode, 'no_combination')
if not success then
unit_table = setmetatable({
symbol = unitcode, name2 = unitcode, utype = unitcode,
scale = 1, default = '', defkey = '', linkey = '' }, unit_mt)
end
local value = tonumber(options.value) or 1
local clean = tostring(abs(value))
local info = {
value = value,
altvalue = value,
singular = (clean == '1'),
clean = clean,
show = clean,
}
unit_table.inout = 'in'
unit_table.valinfo = { info }
local sortspan, scaled_value
if options.sort then
sortspan, scaled_value = make_table_or_sort(parms, value, info, unit_table, options.scaled_top)
end
return {
text = make_id(parms, 1, unit_table),
sortspan = sortspan,
scaled_value = scaled_value,
unknown = not success and true or nil,
}
end
return { convert = main_convert, _unit = _unit }
da3d419635c73ffef0a5bcc2a7d6620979271521
Module:Convert/data
828
47
109
2022-02-13T04:01:16Z
Canopus >Johnuniq
0
update from sandbox per [[Template talk:Convert#Module version 27]]
Scribunto
text/plain
-- Conversion data used by [[Module:Convert]] which uses mw.loadData() for
-- read-only access to this module so that it is loaded only once per page.
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
--
-- These data tables follow:
-- all_units all properties for a unit, including default output
-- default_exceptions exceptions for default output ('kg' and 'g' have different defaults)
-- link_exceptions exceptions for links ('kg' and 'g' have different links)
--
-- These tables are generated by a script which reads the wikitext of a page that
-- documents the required properties of each unit; see [[:en:Module:Convert/doc]].
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local all_units = {
["Gy"] = {
_name1 = "gray",
_symbol = "Gy",
utype = "absorbed radiation dose",
scale = 1,
prefixes = 1,
default = "rad",
link = "Gray (unit)",
},
["rad"] = {
_name1 = "rad",
_symbol = "rad",
utype = "absorbed radiation dose",
scale = 0.01,
prefixes = 1,
default = "Gy",
link = "Rad (unit)",
},
["cm/s2"] = {
name1 = "centimetre per second squared",
name1_us = "centimeter per second squared",
name2 = "centimetres per second squared",
name2_us = "centimeters per second squared",
symbol = "cm/s<sup>2</sup>",
utype = "acceleration",
scale = 0.01,
default = "ft/s2",
link = "Gal (unit)",
},
["ft/s2"] = {
name1 = "foot per second squared",
name2 = "feet per second squared",
symbol = "ft/s<sup>2</sup>",
utype = "acceleration",
scale = 0.3048,
default = "m/s2",
},
["g0"] = {
name1 = "standard gravity",
name2 = "standard gravities",
symbol = "''g''<sub>0</sub>",
utype = "acceleration",
scale = 9.80665,
default = "m/s2",
},
["g-force"] = {
name2 = "''g''",
symbol = "''g''",
utype = "acceleration",
scale = 9.80665,
default = "m/s2",
link = "g-force",
},
["km/hs"] = {
name1 = "kilometre per hour per second",
name1_us = "kilometer per hour per second",
name2 = "kilometres per hour per second",
name2_us = "kilometers per hour per second",
symbol = "km/(h⋅s)",
utype = "acceleration",
scale = 0.27777777777777779,
default = "mph/s",
link = "Acceleration",
},
["km/s2"] = {
name1 = "kilometre per second squared",
name1_us = "kilometer per second squared",
name2 = "kilometres per second squared",
name2_us = "kilometers per second squared",
symbol = "km/s<sup>2</sup>",
utype = "acceleration",
scale = 1000,
default = "mph/s",
link = "Acceleration",
},
["m/s2"] = {
name1 = "metre per second squared",
name1_us = "meter per second squared",
name2 = "metres per second squared",
name2_us = "meters per second squared",
symbol = "m/s<sup>2</sup>",
utype = "acceleration",
scale = 1,
default = "ft/s2",
},
["mph/s"] = {
name1 = "mile per hour per second",
name2 = "miles per hour per second",
symbol = "mph/s",
utype = "acceleration",
scale = 0.44704,
default = "km/hs",
link = "Acceleration",
},
["km/h/s"] = {
target = "km/hs",
},
["standard gravity"] = {
target = "g0",
},
["1000sqft"] = {
name1 = "thousand square feet",
name2 = "thousand square feet",
symbol = "1000 sq ft",
utype = "area",
scale = 92.90304,
default = "m2",
link = "Square foot",
},
["a"] = {
_name1 = "are",
_symbol = "a",
utype = "area",
scale = 100,
prefixes = 1,
default = "sqft",
link = "Hectare#Are",
},
["acre"] = {
symbol = "acre",
usename = 1,
utype = "area",
scale = 4046.8564224,
default = "ha",
subdivs = { ["rood"] = { 4, default = "ha" }, ["sqperch"] = { 160, default = "ha" } },
},
["acre-sing"] = {
target = "acre",
},
["arpent"] = {
symbol = "arpent",
usename = 1,
utype = "area",
scale = 3418.89,
default = "ha",
},
["cda"] = {
name1 = "cuerda",
symbol = "cda",
utype = "area",
scale = 3930.395625,
default = "ha acre",
},
["daa"] = {
name1 = "decare",
symbol = "daa",
utype = "area",
scale = 1000,
default = "km2 sqmi",
},
["dunam"] = {
symbol = "dunam",
usename = 1,
utype = "area",
scale = 1000,
default = "km2 sqmi",
},
["dunum"] = {
symbol = "dunum",
usename = 1,
utype = "area",
scale = 1000,
default = "km2 sqmi",
link = "Dunam",
},
["ha"] = {
name1 = "hectare",
symbol = "ha",
utype = "area",
scale = 10000,
default = "acre",
},
["hectare"] = {
name1 = "hectare",
symbol = "ha",
usename = 1,
utype = "area",
scale = 10000,
default = "acre",
},
["Irish acre"] = {
name1 = "Irish acre",
symbol = "Irish acres",
utype = "area",
scale = 6555.2385024,
default = "ha",
link = "Acre (Irish)",
},
["m2"] = {
_name1 = "square metre",
_name1_us= "square meter",
_symbol = "m<sup>2</sup>",
prefix_position= 8,
utype = "area",
scale = 1,
prefixes = 2,
default = "sqft",
link = "Square metre",
},
["pondemaat"] = {
name1 = "pondemaat",
name2 = "pondemaat",
symbol = "pond",
utype = "area",
scale = 3674.363358816,
default = "m2",
link = ":nl:pondemaat",
},
["pyeong"] = {
name2 = "pyeong",
symbol = "pyeong",
usename = 1,
utype = "area",
scale = 3.3057851239669422,
default = "m2",
},
["rai"] = {
name2 = "rai",
symbol = "rai",
utype = "area",
scale = 1600,
default = "m2",
link = "Rai (unit)",
},
["rood"] = {
symbol = "rood",
usename = 1,
utype = "area",
scale = 1011.7141056,
default = "sqft m2",
subdivs = { ["sqperch"] = { 40, default = "m2" } },
link = "Rood (unit)",
},
["sqfoot"] = {
name1 = "square foot",
name2 = "square foot",
symbol = "sq ft",
utype = "area",
scale = 0.09290304,
default = "m2",
},
["sqft"] = {
name1 = "square foot",
name2 = "square feet",
symbol = "sq ft",
utype = "area",
scale = 0.09290304,
default = "m2",
},
["sqin"] = {
name1 = "square inch",
name2 = "square inches",
symbol = "sq in",
utype = "area",
scale = 0.00064516,
default = "cm2",
},
["sqmi"] = {
name1 = "square mile",
symbol = "sq mi",
utype = "area",
scale = 2589988.110336,
default = "km2",
},
["sqnmi"] = {
name1 = "square nautical mile",
symbol = "sq nmi",
utype = "area",
scale = 3429904,
default = "km2 sqmi",
link = "Nautical mile",
},
["sqperch"] = {
name2 = "perches",
symbol = "perch",
usename = 1,
utype = "area",
scale = 25.29285264,
default = "m2",
link = "Rod (unit)#Area and volume",
},
["sqverst"] = {
symbol = "square verst",
usename = 1,
utype = "area",
scale = 1138062.24,
default = "km2 sqmi",
link = "Verst",
},
["sqyd"] = {
name1 = "square yard",
symbol = "sq yd",
utype = "area",
scale = 0.83612736,
default = "m2",
},
["tsubo"] = {
name2 = "tsubo",
symbol = "tsubo",
usename = 1,
utype = "area",
scale = 3.3057851239669422,
default = "m2",
link = "Japanese units of measurement#Area",
},
["acres"] = {
target = "acre",
},
["are"] = {
target = "a",
},
["decare"] = {
target = "daa",
},
["foot2"] = {
target = "sqfoot",
},
["ft2"] = {
target = "sqft",
},
["in2"] = {
target = "sqin",
symbol = "in<sup>2</sup>",
},
["km²"] = {
target = "km2",
},
["mi2"] = {
target = "sqmi",
},
["million acre"] = {
target = "e6acre",
},
["million acres"] = {
target = "e6acre",
},
["million hectares"] = {
target = "e6ha",
},
["m²"] = {
target = "m2",
},
["nmi2"] = {
target = "sqnmi",
},
["pond"] = {
target = "pondemaat",
},
["sq arp"] = {
target = "arpent",
},
["sqkm"] = {
target = "km2",
},
["sqm"] = {
target = "m2",
},
["square verst"] = {
target = "sqverst",
},
["verst2"] = {
target = "sqverst",
},
["yd2"] = {
target = "sqyd",
},
["m2/ha"] = {
name1 = "square metre per hectare",
name1_us = "square meter per hectare",
name2 = "square metres per hectare",
name2_us = "square meters per hectare",
symbol = "m<sup>2</sup>/ha",
utype = "area per unit area",
scale = 0.0001,
default = "sqft/acre",
link = "Basal area",
},
["sqft/acre"] = {
name1 = "square foot per acre",
name2 = "square feet per acre",
symbol = "sq ft/acre",
utype = "area per unit area",
scale = 2.295684113865932e-5,
default = "m2/ha",
link = "Basal area",
},
["cent"] = {
name1 = "cent",
symbol = "¢",
utype = "cent",
scale = 1,
default = "cent",
link = "Cent (currency)",
},
["¢"] = {
target = "cent",
},
["A.h"] = {
name1 = "ampere hour",
symbol = "A⋅h",
utype = "charge",
scale = 3600,
default = "coulomb",
},
["coulomb"] = {
_name1 = "coulomb",
_symbol = "C",
utype = "charge",
scale = 1,
prefixes = 1,
default = "e",
link = "Coulomb",
},
["e"] = {
name1 = "elementary charge",
symbol = "''e''",
utype = "charge",
scale = 1.602176487e-19,
default = "coulomb",
},
["g-mol"] = {
name1 = "gram-mole",
symbol = "g‑mol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["gmol"] = {
name1 = "gram-mole",
symbol = "gmol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["kmol"] = {
name1 = "kilomole",
symbol = "kmol",
utype = "chemical amount",
scale = 1000,
default = "lbmol",
link = "Mole (unit)",
},
["lb-mol"] = {
name1 = "pound-mole",
symbol = "lb‑mol",
utype = "chemical amount",
scale = 453.59237,
default = "mol",
},
["lbmol"] = {
name1 = "pound-mole",
symbol = "lbmol",
utype = "chemical amount",
scale = 453.59237,
default = "mol",
},
["mol"] = {
name1 = "mole",
symbol = "mol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["kgCO2/L"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg(CO<sub>2</sub>)/L",
utype = "co2 per unit volume",
scale = 1000,
default = "lbCO2/USgal",
link = "Exhaust gas",
},
["lbCO2/USgal"] = {
name1 = "pound per US gallon",
name2 = "pounds per US gallon",
symbol = "lbCO2/US gal",
utype = "co2 per unit volume",
scale = 119.82642731689663,
default = "kgCO2/L",
link = "Exhaust gas",
},
["oz/lb"] = {
per = { "oz", "lb" },
utype = "concentration",
default = "mg/kg",
},
["mg/kg"] = {
per = { "mg", "kg" },
utype = "concentration",
default = "oz/lb",
},
["g/dm3"] = {
name1 = "gram per cubic decimetre",
name1_us = "gram per cubic decimeter",
name2 = "grams per cubic decimetre",
name2_us = "grams per cubic decimeter",
symbol = "g/dm<sup>3</sup>",
utype = "density",
scale = 1,
default = "kg/m3",
link = "Density",
},
["g/L"] = {
name1 = "gram per litre",
name1_us = "gram per liter",
name2 = "grams per litre",
name2_us = "grams per liter",
symbol = "g/L",
utype = "density",
scale = 1,
default = "lb/cuin",
link = "Density",
},
["g/mL"] = {
name1 = "gram per millilitre",
name1_us = "gram per milliliter",
name2 = "grams per millilitre",
name2_us = "grams per milliliter",
symbol = "g/mL",
utype = "density",
scale = 1000,
default = "lb/cuin",
link = "Density",
},
["g/ml"] = {
name1 = "gram per millilitre",
name1_us = "gram per milliliter",
name2 = "grams per millilitre",
name2_us = "grams per milliliter",
symbol = "g/ml",
utype = "density",
scale = 1000,
default = "lb/cuin",
link = "Density",
},
["kg/dm3"] = {
name1 = "kilogram per cubic decimetre",
name1_us = "kilogram per cubic decimeter",
name2 = "kilograms per cubic decimetre",
name2_us = "kilograms per cubic decimeter",
symbol = "kg/dm<sup>3</sup>",
utype = "density",
scale = 1000,
default = "lb/cuft",
link = "Density",
},
["kg/L"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg/L",
utype = "density",
scale = 1000,
default = "lb/USgal",
link = "Density",
},
["kg/l"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg/l",
utype = "density",
scale = 1000,
default = "lb/USgal",
link = "Density",
},
["kg/m3"] = {
name1 = "kilogram per cubic metre",
name1_us = "kilogram per cubic meter",
name2 = "kilograms per cubic metre",
name2_us = "kilograms per cubic meter",
symbol = "kg/m<sup>3</sup>",
utype = "density",
scale = 1,
default = "lb/cuyd",
link = "Density",
},
["lb/cuft"] = {
name1 = "pound per cubic foot",
name2 = "pounds per cubic foot",
symbol = "lb/cu ft",
utype = "density",
scale = 16.018463373960142,
default = "g/cm3",
link = "Density",
},
["lb/cuin"] = {
name1 = "pound per cubic inch",
name2 = "pounds per cubic inch",
symbol = "lb/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["lb/cuyd"] = {
name1 = "pound per cubic yard",
name2 = "pounds per cubic yard",
symbol = "lb/cu yd",
utype = "density",
scale = 0.5932764212577829,
default = "kg/m3",
link = "Density",
},
["lb/impgal"] = {
name1 = "pound per imperial gallon",
name2 = "pounds per imperial gallon",
symbol = "lb/imp gal",
utype = "density",
scale = 99.776372663101697,
default = "kg/L",
link = "Density",
},
["lb/in3"] = {
name1 = "pound per cubic inch",
name2 = "pounds per cubic inch",
symbol = "lb/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["lb/U.S.gal"] = {
name1 = "pound per U.S. gallon",
name2 = "pounds per U.S. gallon",
symbol = "lb/U.S. gal",
utype = "density",
scale = 119.82642731689663,
default = "kg/L",
link = "Density",
},
["lb/USbu"] = {
name1 = "pound per US bushel",
name2 = "pounds per US bushel",
symbol = "lb/US bu",
utype = "density",
scale = 12.871859780974471,
default = "kg/m3",
link = "Bushel",
},
["lb/USgal"] = {
name1 = "pound per US gallon",
name2 = "pounds per US gallon",
symbol = "lb/US gal",
utype = "density",
scale = 119.82642731689663,
default = "kg/L",
link = "Density",
},
["lbm/cuin"] = {
name1 = "pound mass per cubic inch",
name2 = "pounds mass per cubic inch",
symbol = "lbm/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["mg/L"] = {
name1 = "milligram per litre",
name1_us = "milligram per liter",
name2 = "milligrams per litre",
name2_us = "milligrams per liter",
symbol = "mg/L",
utype = "density",
scale = 0.001,
default = "lb/cuin",
link = "Density",
},
["oz/cuin"] = {
name1 = "ounce per cubic inch",
name2 = "ounces per cubic inch",
symbol = "oz/cu in",
utype = "density",
scale = 1729.9940443876951,
default = "g/cm3",
link = "Density",
},
["g/cm3"] = {
per = { "g", "cm3" },
utype = "density",
default = "lb/cuin",
},
["g/m3"] = {
per = { "g", "m3" },
utype = "density",
default = "lb/cuyd",
link = "Density",
},
["Mg/m3"] = {
per = { "Mg", "m3" },
utype = "density",
default = "lb/cuft",
},
["mg/l"] = {
per = { "mg", "l" },
utype = "density",
default = "oz/cuin",
},
["μg/dL"] = {
per = { "μg", "dL" },
utype = "density",
default = "lb/cuin",
},
["μg/l"] = {
per = { "μg", "l" },
utype = "density",
default = "oz/cuin",
},
["lb/ft3"] = {
target = "lb/cuft",
},
["lb/yd3"] = {
target = "lb/cuyd",
},
["lbm/in3"] = {
target = "lbm/cuin",
},
["mcg/dL"] = {
target = "μg/dL",
},
["oz/in3"] = {
target = "oz/cuin",
},
["ug/dL"] = {
target = "μg/dL",
},
["ug/l"] = {
target = "μg/l",
},
["B.O.T.U."] = {
name1 = "Board of Trade Unit",
symbol = "B.O.T.U.",
utype = "energy",
scale = 3600000,
default = "MJ",
link = "Kilowatt-hour",
},
["bboe"] = {
name1 = "barrel of oil equivalent",
name2 = "barrels of oil equivalent",
symbol = "bboe",
utype = "energy",
scale = 6117863200,
default = "GJ",
},
["BOE"] = {
name1 = "barrel of oil equivalent",
name2 = "barrels of oil equivalent",
symbol = "BOE",
utype = "energy",
scale = 6117863200,
default = "GJ",
},
["BTU"] = {
name1 = "British thermal unit",
symbol = "BTU",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
},
["Btu"] = {
name1 = "British thermal unit",
symbol = "Btu",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
},
["BTU-39F"] = {
name1 = "British thermal unit (39°F)",
name2 = "British thermal units (39°F)",
symbol = "BTU<sub>39°F</sub>",
utype = "energy",
scale = 1059.67,
default = "kJ",
link = "British thermal unit",
},
["Btu-39F"] = {
name1 = "British thermal unit (39°F)",
name2 = "British thermal units (39°F)",
symbol = "Btu<sub>39°F</sub>",
utype = "energy",
scale = 1059.67,
default = "kJ",
link = "British thermal unit",
},
["BTU-59F"] = {
name1 = "British thermal unit (59°F)",
name2 = "British thermal units (59°F)",
symbol = "BTU<sub>59°F</sub>",
utype = "energy",
scale = 1054.804,
default = "kJ",
link = "British thermal unit",
},
["Btu-59F"] = {
name1 = "British thermal unit (59°F)",
name2 = "British thermal units (59°F)",
symbol = "Btu<sub>59°F</sub>",
utype = "energy",
scale = 1054.804,
default = "kJ",
link = "British thermal unit",
},
["BTU-60F"] = {
name1 = "British thermal unit (60°F)",
name2 = "British thermal units (60°F)",
symbol = "BTU<sub>60°F</sub>",
utype = "energy",
scale = 1054.68,
default = "kJ",
link = "British thermal unit",
},
["Btu-60F"] = {
name1 = "British thermal unit (60°F)",
name2 = "British thermal units (60°F)",
symbol = "Btu<sub>60°F</sub>",
utype = "energy",
scale = 1054.68,
default = "kJ",
link = "British thermal unit",
},
["BTU-63F"] = {
name1 = "British thermal unit (63°F)",
name2 = "British thermal units (63°F)",
symbol = "BTU<sub>63°F</sub>",
utype = "energy",
scale = 1054.6,
default = "kJ",
link = "British thermal unit",
},
["Btu-63F"] = {
name1 = "British thermal unit (63°F)",
name2 = "British thermal units (63°F)",
symbol = "Btu<sub>63°F</sub>",
utype = "energy",
scale = 1054.6,
default = "kJ",
link = "British thermal unit",
},
["BTU-ISO"] = {
name1 = "British thermal unit (ISO)",
name2 = "British thermal units (ISO)",
symbol = "BTU<sub>ISO</sub>",
utype = "energy",
scale = 1055.056,
default = "kJ",
link = "British thermal unit",
},
["Btu-ISO"] = {
target = "BTU-ISO",
},
["BTU-IT"] = {
name1 = "British thermal unit (IT)",
name2 = "British thermal units (IT)",
symbol = "BTU<sub>IT</sub>",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
link = "British thermal unit",
},
["Btu-IT"] = {
name1 = "British thermal unit (IT)",
name2 = "British thermal units (IT)",
symbol = "Btu<sub>IT</sub>",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
link = "British thermal unit",
},
["BTU-mean"] = {
name1 = "British thermal unit (mean)",
name2 = "British thermal units (mean)",
symbol = "BTU<sub>mean</sub>",
utype = "energy",
scale = 1055.87,
default = "kJ",
link = "British thermal unit",
},
["Btu-mean"] = {
name1 = "British thermal unit (mean)",
name2 = "British thermal units (mean)",
symbol = "Btu<sub>mean</sub>",
utype = "energy",
scale = 1055.87,
default = "kJ",
link = "British thermal unit",
},
["BTU-th"] = {
name1 = "British thermal unit (thermochemical)",
name2 = "British thermal units (thermochemical)",
symbol = "BTU<sub>th</sub>",
utype = "energy",
scale = 1054.35026444,
default = "kJ",
link = "British thermal unit",
},
["Btu-th"] = {
name1 = "British thermal unit (thermochemical)",
name2 = "British thermal units (thermochemical)",
symbol = "Btu<sub>th</sub>",
utype = "energy",
scale = 1054.35026444,
default = "kJ",
link = "British thermal unit",
},
["Cal"] = {
name1 = "calorie",
symbol = "Cal",
utype = "energy",
scale = 4184,
default = "kJ",
},
["cal"] = {
name1 = "calorie",
symbol = "cal",
utype = "energy",
scale = 4.184,
default = "J",
},
["Cal-15"] = {
name1 = "Calorie (15°C)",
name2 = "Calories (15°C)",
symbol = "Cal<sub>15</sub>",
utype = "energy",
scale = 4185.8,
default = "kJ",
link = "Calorie",
},
["cal-15"] = {
name1 = "calorie (15°C)",
name2 = "calories (15°C)",
symbol = "cal<sub>15</sub>",
utype = "energy",
scale = 4.1858,
default = "J",
link = "Calorie",
},
["Cal-IT"] = {
name1 = "Calorie (International Steam Table)",
name2 = "Calories (International Steam Table)",
symbol = "Cal<sub>IT</sub>",
utype = "energy",
scale = 4186.8,
default = "kJ",
link = "Calorie",
},
["cal-IT"] = {
name1 = "calorie (International Steam Table)",
name2 = "calories (International Steam Table)",
symbol = "cal<sub>IT</sub>",
utype = "energy",
scale = 4.1868,
default = "J",
link = "Calorie",
},
["Cal-th"] = {
name1 = "Calorie (thermochemical)",
name2 = "Calories (thermochemical)",
symbol = "Cal<sub>th</sub>",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["cal-th"] = {
name1 = "calorie (thermochemical)",
name2 = "calories (thermochemical)",
symbol = "cal<sub>th</sub>",
utype = "energy",
scale = 4.184,
default = "J",
link = "Calorie",
},
["CHU-IT"] = {
name1 = "Celsius heat unit (International Table)",
name2 = "Celsius heat units (International Table)",
symbol = "CHU<sub>IT</sub>",
utype = "energy",
scale = 1899.100534716,
default = "kJ",
link = "Conversion of units#Energy",
},
["cufootnaturalgas"] = {
name1 = "cubic foot of natural gas",
name2 = "cubic foot of natural gas",
symbol = "cuftnaturalgas",
usename = 1,
utype = "energy",
scale = 1055055.85262,
default = "MJ",
link = "Conversion of units#Energy",
},
["cuftnaturalgas"] = {
name1 = "cubic foot of natural gas",
name2 = "cubic feet of natural gas",
symbol = "cuftnaturalgas",
usename = 1,
utype = "energy",
scale = 1055055.85262,
default = "MJ",
link = "Conversion of units#Energy",
},
["Eh"] = {
name1 = "Hartree",
symbol = "''E''<sub>h</sub>",
utype = "energy",
scale = 4.35974417e-18,
default = "eV",
},
["erg"] = {
symbol = "erg",
utype = "energy",
scale = 0.0000001,
default = "μJ",
},
["eV"] = {
name1 = "electronvolt",
symbol = "eV",
utype = "energy",
scale = 1.602176487e-19,
default = "aJ",
},
["feV"] = {
name1 = "femtoelectronvolt",
symbol = "feV",
utype = "energy",
scale = 1.602176487e-34,
default = "yJ",
link = "Electronvolt",
},
["foe"] = {
symbol = "foe",
utype = "energy",
scale = 1e44,
default = "YJ",
link = "Foe (unit)",
},
["ftlb"] = {
name1 = "foot-pound",
symbol = "ft⋅lb",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftlb-f"] = {
name1 = "foot-pound force",
name2 = "foot-pounds force",
symbol = "ft⋅lb<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftlbf"] = {
name1 = "foot-pound force",
name2 = "foot-pounds force",
symbol = "ft⋅lbf",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftpdl"] = {
name1 = "foot-poundal",
symbol = "ft⋅pdl",
utype = "energy",
scale = 0.0421401100938048,
default = "J",
},
["GeV"] = {
name1 = "gigaelectronvolt",
symbol = "GeV",
utype = "energy",
scale = 1.602176487e-10,
default = "nJ",
link = "Electronvolt",
},
["gTNT"] = {
name2 = "grams of TNT",
symbol = "gram of TNT",
usename = 1,
utype = "energy",
scale = 4184,
default = "kJ",
link = "TNT equivalent",
},
["Gtoe"] = {
name1 = "gigatonne of oil equivalent",
name2 = "gigatonnes of oil equivalent",
symbol = "Gtoe",
utype = "energy",
scale = 4.1868e19,
default = "EJ",
link = "Tonne of oil equivalent",
},
["GtonTNT"] = {
name2 = "gigatons of TNT",
symbol = "gigaton of TNT",
usename = 1,
utype = "energy",
scale = 4.184e18,
default = "EJ",
link = "TNT equivalent",
},
["GtTNT"] = {
name2 = "gigatonnes of TNT",
symbol = "gigatonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e18,
default = "EJ",
link = "TNT equivalent",
},
["GW.h"] = {
name1 = "gigawatt-hour",
symbol = "GW⋅h",
utype = "energy",
scale = 3.6e12,
default = "TJ",
link = "Kilowatt-hour",
},
["GWh"] = {
name1 = "gigawatt-hour",
symbol = "GWh",
utype = "energy",
scale = 3.6e12,
default = "TJ",
link = "Kilowatt-hour",
},
["hph"] = {
name1 = "horsepower-hour",
symbol = "hp⋅h",
utype = "energy",
scale = 2684519.537696172792,
default = "kWh",
link = "Horsepower",
},
["inlb"] = {
name1 = "inch-pound",
symbol = "in⋅lb",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inlb-f"] = {
name1 = "inch-pound force",
name2 = "inch-pounds force",
symbol = "in⋅lb<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inlbf"] = {
name1 = "inch-pound force",
name2 = "inch-pounds force",
symbol = "in⋅lbf",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inoz-f"] = {
name1 = "inch-ounce force",
name2 = "inch-ounces force",
symbol = "in⋅oz<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 0.00706155181422604375,
default = "mJ",
link = "Foot-pound (energy)",
},
["inozf"] = {
name1 = "inch-ounce force",
name2 = "inch-ounces force",
symbol = "in⋅ozf",
utype = "energy",
alttype = "torque",
scale = 0.00706155181422604375,
default = "mJ",
link = "Foot-pound (energy)",
},
["J"] = {
_name1 = "joule",
_symbol = "J",
utype = "energy",
scale = 1,
prefixes = 1,
default = "cal",
link = "Joule",
},
["kBOE"] = {
name1 = "kilo barrel of oil equivalent",
name2 = "kilo barrels of oil equivalent",
symbol = "kBOE",
utype = "energy",
scale = 6.1178632e12,
default = "TJ",
link = "Barrel of oil equivalent",
},
["kcal"] = {
name1 = "kilocalorie",
symbol = "kcal",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["kcal-15"] = {
name1 = "kilocalorie (15°C)",
name2 = "kilocalories (15°C)",
symbol = "kcal<sub>15</sub>",
utype = "energy",
scale = 4185.8,
default = "kJ",
link = "Calorie",
},
["kcal-IT"] = {
name1 = "kilocalorie (International Steam Table)",
name2 = "kilocalories (International Steam Table)",
symbol = "kcal<sub>IT</sub>",
utype = "energy",
scale = 4186.8,
default = "kJ",
link = "Calorie",
},
["kcal-th"] = {
name1 = "kilocalorie (thermochemical)",
name2 = "kilocalories (thermochemical)",
symbol = "kcal<sub>th</sub>",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["kerg"] = {
name1 = "kiloerg",
symbol = "kerg",
utype = "energy",
scale = 0.0001,
default = "mJ",
link = "Erg",
},
["keV"] = {
name1 = "kiloelectronvolt",
symbol = "keV",
utype = "energy",
scale = 1.602176487e-16,
default = "fJ",
link = "Electronvolt",
},
["kgTNT"] = {
name2 = "kilograms of TNT",
symbol = "kilogram of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["kt(TNT)"] = {
name1 = "kilotonne",
name1_us = "kiloton",
symbol = "kt",
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["ktoe"] = {
name1 = "kilotonne of oil equivalent",
name2 = "kilotonnes of oil equivalent",
symbol = "ktoe",
utype = "energy",
scale = 4.1868e13,
default = "TJ",
link = "Tonne of oil equivalent",
},
["ktonTNT"] = {
name1 = "kiloton of TNT",
name2 = "kilotons of TNT",
symbol = "kt",
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["ktTNT"] = {
name2 = "kilotonnes of TNT",
symbol = "kilotonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["kW.h"] = {
name1 = "kilowatt-hour",
symbol = "kW⋅h",
utype = "energy",
scale = 3600000,
default = "MJ",
},
["kWh"] = {
name1 = "kilowatt-hour",
symbol = "kWh",
utype = "energy",
scale = 3600000,
default = "MJ",
},
["Mcal"] = {
name1 = "megacalorie",
symbol = "Mcal",
utype = "energy",
scale = 4184000,
default = "MJ",
link = "Calorie",
},
["mcal"] = {
name1 = "millicalorie",
symbol = "mcal",
utype = "energy",
scale = 0.004184,
default = "mJ",
link = "Calorie",
},
["Mcal-15"] = {
name1 = "megacalorie (15°C)",
name2 = "megacalories (15°C)",
symbol = "Mcal<sub>15</sub>",
utype = "energy",
scale = 4185800,
default = "MJ",
link = "Calorie",
},
["mcal-15"] = {
name1 = "millicalorie (15°C)",
name2 = "millicalories (15°C)",
symbol = "mcal<sub>15</sub>",
utype = "energy",
scale = 0.0041858,
default = "mJ",
link = "Calorie",
},
["Mcal-IT"] = {
name1 = "megacalorie (International Steam Table)",
name2 = "megacalories (International Steam Table)",
symbol = "Mcal<sub>IT</sub>",
utype = "energy",
scale = 4186800,
default = "MJ",
link = "Calorie",
},
["mcal-IT"] = {
name1 = "millicalorie (International Steam Table)",
name2 = "millicalories (International Steam Table)",
symbol = "mcal<sub>IT</sub>",
utype = "energy",
scale = 0.0041868,
default = "mJ",
link = "Calorie",
},
["Mcal-th"] = {
name1 = "megacalorie (thermochemical)",
name2 = "megacalories (thermochemical)",
symbol = "Mcal<sub>th</sub>",
utype = "energy",
scale = 4184000,
default = "MJ",
link = "Calorie",
},
["mcal-th"] = {
name1 = "millicalorie (thermochemical)",
name2 = "millicalories (thermochemical)",
symbol = "mcal<sub>th</sub>",
utype = "energy",
scale = 0.004184,
default = "mJ",
link = "Calorie",
},
["Merg"] = {
name1 = "megaerg",
symbol = "Merg",
utype = "energy",
scale = 0.1,
default = "J",
link = "Erg",
},
["merg"] = {
name1 = "millierg",
symbol = "merg",
utype = "energy",
scale = 0.0000000001,
default = "μJ",
link = "Erg",
},
["MeV"] = {
name1 = "megaelectronvolt",
symbol = "MeV",
utype = "energy",
scale = 1.602176487e-13,
default = "pJ",
link = "Electronvolt",
},
["meV"] = {
name1 = "millielectronvolt",
symbol = "meV",
utype = "energy",
scale = 1.602176487e-22,
default = "zJ",
link = "Electronvolt",
},
["MMBtu"] = {
name1 = "million British thermal units",
name2 = "million British thermal units",
symbol = "MMBtu",
utype = "energy",
scale = 1055055852.62,
default = "GJ",
link = "British thermal unit",
},
["Mt(TNT)"] = {
name1 = "megatonne",
name1_us = "megaton",
symbol = "Mt",
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["Mtoe"] = {
name1 = "megatonne of oil equivalent",
name2 = "megatonnes of oil equivalent",
symbol = "Mtoe",
utype = "energy",
scale = 4.1868e16,
default = "PJ",
link = "Tonne of oil equivalent",
},
["MtonTNT"] = {
name1 = "megaton of TNT",
name2 = "megatons of TNT",
symbol = "Mt",
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["mtonTNT"] = {
name2 = "millitons of TNT",
symbol = "milliton of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["MtTNT"] = {
name2 = "megatonnes of TNT",
symbol = "megatonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["mtTNT"] = {
name2 = "millitonnes of TNT",
symbol = "millitonne of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["MW.h"] = {
name1 = "megawatt-hour",
symbol = "MW⋅h",
utype = "energy",
scale = 3600000000,
default = "GJ",
link = "Kilowatt-hour",
},
["mW.h"] = {
name1 = "milliwatt-hour",
symbol = "mW⋅h",
utype = "energy",
scale = 3.6,
default = "J",
link = "Kilowatt-hour",
},
["MWh"] = {
name1 = "megawatt-hour",
symbol = "MWh",
utype = "energy",
scale = 3600000000,
default = "GJ",
link = "Kilowatt-hour",
},
["mWh"] = {
name1 = "milliwatt-hour",
symbol = "mWh",
utype = "energy",
scale = 3.6,
default = "J",
link = "Kilowatt-hour",
},
["neV"] = {
name1 = "nanoelectronvolt",
symbol = "neV",
utype = "energy",
scale = 1.602176487e-28,
default = "yJ",
link = "Electronvolt",
},
["PeV"] = {
name1 = "petaelectronvolt",
symbol = "PeV",
utype = "energy",
scale = 0.0001602176487,
default = "mJ",
link = "Electronvolt",
},
["peV"] = {
name1 = "picoelectronvolt",
symbol = "peV",
utype = "energy",
scale = 1.602176487e-31,
default = "yJ",
link = "Electronvolt",
},
["PSh"] = {
name1 = "Pferdestärkenstunde",
symbol = "PSh",
utype = "energy",
scale = 2647795.5,
default = "kWh",
},
["quad"] = {
name1 = "quadrillion British thermal units",
name2 = "quadrillion British thermal units",
symbol = "quad",
utype = "energy",
scale = 1.054804e18,
default = "EJ",
link = "Quad (unit)",
},
["Ry"] = {
name1 = "rydberg",
symbol = "Ry",
utype = "energy",
scale = 2.1798741e-18,
default = "eV",
link = "Rydberg constant",
},
["scf"] = {
name1 = "standard cubic foot",
name2 = "standard cubic feet",
symbol = "scf",
utype = "energy",
scale = 2869.2044809344,
default = "kJ",
},
["scfoot"] = {
name1 = "standard cubic foot",
name2 = "standard cubic foot",
symbol = "scf",
utype = "energy",
scale = 2869.2044809344,
default = "kJ",
},
["t(TNT)"] = {
name1 = "tonne",
name1_us = "ton",
symbol = "t",
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["TeV"] = {
name1 = "teraelectronvolt",
symbol = "TeV",
utype = "energy",
scale = 1.602176487e-7,
default = "μJ",
link = "Electronvolt",
},
["th"] = {
name1 = "thermie",
symbol = "th",
utype = "energy",
scale = 4186800,
default = "MJ",
link = "Conversion of units#Energy",
},
["thm-EC"] = {
name1 = "therm (EC)",
name2 = "therms (EC)",
symbol = "thm (EC)",
utype = "energy",
scale = 105506000,
default = "MJ",
link = "Therm",
},
["thm-UK"] = {
name1 = "therm (UK)",
name2 = "therms (UK)",
symbol = "thm (UK)",
utype = "energy",
scale = 105505585.257348,
default = "MJ",
link = "Therm",
},
["thm-US"] = {
name1 = "therm (US)",
name1_us = "therm (U.S.)",
name2 = "therms (US)",
name2_us = "therms (U.S.)",
symbol = "thm (US)",
sym_us = "thm (U.S.)",
utype = "energy",
scale = 105480400,
default = "MJ",
link = "Therm",
},
["toe"] = {
name1 = "tonne of oil equivalent",
name2 = "tonnes of oil equivalent",
symbol = "toe",
utype = "energy",
scale = 41868000000,
default = "GJ",
},
["tonTNT"] = {
name2 = "tons of TNT",
symbol = "ton of TNT",
usename = 1,
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["tTNT"] = {
name2 = "tonnes of TNT",
symbol = "tonne of TNT",
usename = 1,
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["TtonTNT"] = {
name2 = "teratons of TNT",
symbol = "teraton of TNT",
usename = 1,
utype = "energy",
scale = 4.184e21,
default = "ZJ",
link = "TNT equivalent",
},
["TtTNT"] = {
name2 = "teratonnes of TNT",
symbol = "teratonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e21,
default = "ZJ",
link = "TNT equivalent",
},
["TW.h"] = {
name1 = "terawatt-hour",
symbol = "TW⋅h",
utype = "energy",
scale = 3.6e15,
default = "PJ",
link = "Kilowatt-hour",
},
["TWh"] = {
name1 = "terawatt-hour",
symbol = "TWh",
utype = "energy",
scale = 3.6e15,
default = "PJ",
link = "Kilowatt-hour",
},
["W.h"] = {
name1 = "watt-hour",
symbol = "W⋅h",
utype = "energy",
scale = 3600,
default = "kJ",
link = "Kilowatt-hour",
},
["Wh"] = {
name1 = "watt-hour",
symbol = "Wh",
utype = "energy",
scale = 3600,
default = "kJ",
link = "Kilowatt-hour",
},
["μerg"] = {
name1 = "microerg",
symbol = "μerg",
utype = "energy",
scale = 1e-13,
default = "nJ",
link = "Erg",
},
["μeV"] = {
name1 = "microelectronvolt",
symbol = "μeV",
utype = "energy",
scale = 1.602176487e-25,
default = "yJ",
link = "Electronvolt",
},
["μW.h"] = {
name1 = "microwatt-hour",
symbol = "μW⋅h",
utype = "energy",
scale = 0.0036,
default = "mJ",
link = "Kilowatt-hour",
},
["μWh"] = {
name1 = "microwatt-hour",
symbol = "μWh",
utype = "energy",
scale = 0.0036,
default = "mJ",
link = "Kilowatt-hour",
},
["-kW.h"] = {
target = "kW.h",
link = "Kilowatt hour",
},
["btu"] = {
target = "BTU",
},
["Calorie"] = {
target = "Cal",
},
["ft.lbf"] = {
target = "ftlbf",
},
["ft·lbf"] = {
target = "ftlbf",
},
["g-cal-15"] = {
target = "cal-15",
},
["g-cal-IT"] = {
target = "cal-IT",
},
["g-cal-th"] = {
target = "cal-th",
},
["g-kcal-15"] = {
target = "kcal-15",
},
["g-kcal-IT"] = {
target = "kcal-IT",
},
["g-kcal-th"] = {
target = "kcal-th",
},
["g-Mcal-15"] = {
target = "Mcal-15",
},
["g-mcal-15"] = {
target = "mcal-15",
},
["g-Mcal-IT"] = {
target = "Mcal-IT",
},
["g-mcal-IT"] = {
target = "mcal-IT",
},
["g-Mcal-th"] = {
target = "Mcal-th",
},
["g-mcal-th"] = {
target = "mcal-th",
},
["GW-h"] = {
target = "GW.h",
},
["GW·h"] = {
target = "GW.h",
},
["Hartree"] = {
target = "Eh",
},
["hp.h"] = {
target = "hph",
},
["in.lb-f"] = {
target = "inlb-f",
},
["in.lbf"] = {
target = "inlbf",
},
["in.oz-f"] = {
target = "inoz-f",
},
["in.ozf"] = {
target = "inozf",
},
["kbboe"] = {
target = "kBOE",
symbol = "kbboe",
},
["kg-cal-15"] = {
target = "Cal-15",
},
["kg-cal-IT"] = {
target = "Cal-IT",
},
["kg-cal-th"] = {
target = "Cal-th",
},
["kW-h"] = {
target = "kW.h",
},
["kW·h"] = {
target = "kW.h",
},
["MW-h"] = {
target = "MW.h",
},
["mW-h"] = {
target = "mW.h",
},
["MW·h"] = {
target = "MW.h",
},
["TW-h"] = {
target = "TW.h",
},
["uerg"] = {
target = "μerg",
},
["ueV"] = {
target = "μeV",
},
["uW-h"] = {
target = "μW.h",
},
["uW.h"] = {
target = "μW.h",
},
["uWh"] = {
target = "μWh",
},
["W-h"] = {
target = "W.h",
},
["eVpar"] = {
_name1 = "electronvolt",
_symbol = "eV",
utype = "energy per chemical amount",
scale = 96485.329522144166,
prefixes = 1,
default = "kcal/mol",
link = "Electronvolt",
},
["kcal/mol"] = {
per = { "kcal", "mol" },
utype = "energy per chemical amount",
default = "kJ/mol",
link = "Kilocalorie per mole",
},
["kJ/mol"] = {
per = { "kJ", "mol" },
utype = "energy per chemical amount",
default = "kcal/mol",
link = "Joule per mole",
},
["kWh/100 km"] = {
name1 = "kilowatt-hour per 100 kilometres",
name1_us = "kilowatt-hour per 100 kilometers",
name2 = "kilowatt-hours per 100 kilometres",
name2_us = "kilowatt-hours per 100 kilometers",
symbol = "kW⋅h/100 km",
utype = "energy per unit length",
scale = 36,
default = "MJ/km kWh/mi",
link = "Kilowatt-hour",
},
["kWh/100 mi"] = {
name1 = "kilowatt-hour per 100 miles",
name2 = "kilowatt-hours per 100 miles",
symbol = "kW⋅h/100 mi",
utype = "energy per unit length",
scale = 22.3694,
default = "mpge",
link = "Miles per gallon gasoline equivalent",
},
["MJ/100 km"] = {
name1 = "megajoule per 100 kilometres",
name1_us = "megajoule per 100 kilometers",
name2 = "megajoules per 100 kilometres",
name2_us = "megajoules per 100 kilometers",
symbol = "MJ/100 km",
utype = "energy per unit length",
scale = 10,
default = "BTU/mi",
link = "British thermal unit",
},
["mpge"] = {
name1 = "mile per gallon gasoline equivalent",
name2 = "miles per gallon gasoline equivalent",
symbol = "mpg‑e",
utype = "energy per unit length",
scale = 13e-6,
invert = -1,
iscomplex= true,
default = "kWh/100 mi",
link = "Miles per gallon gasoline equivalent",
},
["BTU/mi"] = {
per = { "BTU", "mi" },
utype = "energy per unit length",
default = "v > 1525 ! M ! k ! J/km",
},
["kJ/km"] = {
per = { "kJ", "km" },
utype = "energy per unit length",
default = "BTU/mi",
},
["kWh/km"] = {
per = { "-kW.h", "km" },
utype = "energy per unit length",
default = "MJ/km kWh/mi",
},
["kWh/mi"] = {
per = { "-kW.h", "mi" },
utype = "energy per unit length",
default = "kWh/km MJ/km",
},
["MJ/km"] = {
per = { "MJ", "km" },
utype = "energy per unit length",
default = "BTU/mi",
},
["mpg-e"] = {
target = "mpge",
},
["BTU/lb"] = {
name1 = "British thermal unit per pound",
name2 = "British thermal units per pound",
symbol = "BTU/lb",
utype = "energy per unit mass",
scale = 429.92261414790346,
default = "kJ/kg",
link = "British thermal unit",
},
["cal/g"] = {
name1 = "calorie per gram",
name2 = "calories per gram",
symbol = "cal/g",
utype = "energy per unit mass",
scale = 4184,
default = "J/g",
},
["GJ/kg"] = {
name1 = "gigajoule per kilogram",
name2 = "gigajoules per kilogram",
symbol = "GJ/kg",
utype = "energy per unit mass",
scale = 1e9,
default = "ktTNT/t",
link = "Specific energy",
},
["J/g"] = {
name1 = "joule per gram",
name2 = "joules per gram",
symbol = "J/g",
utype = "energy per unit mass",
scale = 1000,
default = "kcal/g",
link = "Specific energy",
},
["kcal/g"] = {
name1 = "kilocalorie per gram",
name2 = "kilocalories per gram",
symbol = "kcal/g",
utype = "energy per unit mass",
scale = 4184000,
default = "kJ/g",
},
["kJ/g"] = {
name1 = "kilojoule per gram",
name2 = "kilojoules per gram",
symbol = "kJ/g",
utype = "energy per unit mass",
scale = 1000000,
default = "kcal/g",
link = "Specific energy",
},
["kJ/kg"] = {
name1 = "kilojoule per kilogram",
name2 = "kilojoules per kilogram",
symbol = "kJ/kg",
utype = "energy per unit mass",
scale = 1000,
default = "BTU/lb",
link = "Specific energy",
},
["ktonTNT/MT"] = {
name2 = "kilotons of TNT per metric ton",
symbol = "kiloton of TNT per metric ton",
usename = 1,
utype = "energy per unit mass",
scale = 4184000000,
default = "GJ/kg",
link = "TNT equivalent",
},
["ktTNT/t"] = {
name2 = "kilotonnes of TNT per tonne",
symbol = "kilotonne of TNT per tonne",
usename = 1,
utype = "energy per unit mass",
scale = 4184000000,
default = "GJ/kg",
link = "TNT equivalent",
},
["MtonTNT/MT"] = {
name2 = "megatons of TNT per metric ton",
symbol = "megaton of TNT per metric ton",
usename = 1,
utype = "energy per unit mass",
scale = 4.184e12,
default = "TJ/kg",
link = "TNT equivalent",
},
["MtTNT/MT"] = {
name2 = "megatonnes of TNT per tonne",
symbol = "megatonne of TNT per tonne",
usename = 1,
utype = "energy per unit mass",
scale = 4.184e12,
default = "TJ/kg",
link = "TNT equivalent",
},
["TJ/kg"] = {
name1 = "terajoule per kilogram",
name2 = "terajoules per kilogram",
symbol = "TJ/kg",
utype = "energy per unit mass",
scale = 1e12,
default = "MtTNT/MT",
link = "Specific energy",
},
["Cal/g"] = {
per = { "Cal", "g" },
utype = "energy per unit mass",
default = "kJ/g",
},
["BTU/cuft"] = {
per = { "BTU", "cuft" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/12USoz(mL)serve"] = {
per = { "Cal", "-12USoz(mL)serve" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/12USoz(ml)serve"] = {
per = { "Cal", "-12USoz(ml)serve" },
utype = "energy per unit volume",
default = "kJ/l",
},
["Cal/12USozserve"] = {
per = { "Cal", "-12USozserve" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/USoz"] = {
per = { "Cal", "USoz" },
utype = "energy per unit volume",
default = "kJ/ml",
},
["kJ/L"] = {
per = { "kJ", "L" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["kJ/l"] = {
per = { "kJ", "l" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["kJ/ml"] = {
per = { "kJ", "ml" },
utype = "energy per unit volume",
default = "Cal/USoz",
},
["MJ/m3"] = {
per = { "MJ", "m3" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["Sv"] = {
_name1 = "sievert",
_symbol = "Sv",
utype = "equivalent radiation dose",
scale = 1,
prefixes = 1,
default = "rem",
link = "Sievert",
},
["rem"] = {
_name1 = "rem",
_symbol = "rem",
utype = "equivalent radiation dose",
scale = 0.01,
prefixes = 1,
default = "Sv",
link = "Roentgen equivalent man",
},
["g/km"] = {
name1 = "gram per kilometre",
name1_us = "gram per kilometer",
name2 = "grams per kilometre",
name2_us = "grams per kilometer",
symbol = "g/km",
utype = "exhaust emission",
scale = 1e-6,
default = "oz/mi",
link = "Exhaust gas",
},
["g/mi"] = {
name1 = "gram per mile",
name2 = "grams per mile",
symbol = "g/mi",
utype = "exhaust emission",
scale = 6.2137119223733397e-7,
default = "g/km",
link = "Exhaust gas",
},
["gCO2/km"] = {
name1 = "gram of CO<sub>2</sub> per kilometre",
name1_us = "gram of CO<sub>2</sub> per kilometer",
name2 = "grams of CO<sub>2</sub> per kilometre",
name2_us = "grams of CO<sub>2</sub> per kilometer",
symbol = "g(CO<sub>2</sub>)/km",
utype = "exhaust emission",
scale = 1e-6,
default = "ozCO2/mi",
link = "Exhaust gas",
},
["gCO2/mi"] = {
name1 = "gram of CO<sub>2</sub> per mile",
name2 = "grams of CO<sub>2</sub> per mile",
symbol = "g(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 6.2137119223733397e-7,
default = "gCO2/km",
link = "Exhaust gas",
},
["kg/km"] = {
name1 = "kilogram per kilometre",
name1_us = "kilogram per kilometer",
name2 = "kilograms per kilometre",
name2_us = "kilograms per kilometer",
symbol = "kg/km",
utype = "exhaust emission",
scale = 0.001,
default = "lb/mi",
link = "Exhaust gas",
},
["kgCO2/km"] = {
name1 = "kilogram of CO<sub>2</sub> per kilometre",
name1_us = "kilogram of CO<sub>2</sub> per kilometer",
name2 = "kilograms of CO<sub>2</sub> per kilometre",
name2_us = "kilograms of CO<sub>2</sub> per kilometer",
symbol = "kg(CO<sub>2</sub>)/km",
utype = "exhaust emission",
scale = 0.001,
default = "lbCO2/mi",
link = "Exhaust gas",
},
["lb/mi"] = {
name1 = "pound per mile",
name2 = "pounds per mile",
symbol = "lb/mi",
utype = "exhaust emission",
scale = 0.00028184923173665794,
default = "kg/km",
link = "Exhaust gas",
},
["lbCO2/mi"] = {
name1 = "pound of CO<sub>2</sub> per mile",
name2 = "pounds of CO<sub>2</sub> per mile",
symbol = "lb(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 0.00028184923173665794,
default = "kgCO2/km",
link = "Exhaust gas",
},
["oz/mi"] = {
name1 = "ounce per mile",
name2 = "ounces per mile",
symbol = "oz/mi",
utype = "exhaust emission",
scale = 1.7615576983541121e-5,
default = "g/km",
link = "Exhaust gas",
},
["ozCO2/mi"] = {
name1 = "ounce of CO<sub>2</sub> per mile",
name2 = "ounces of CO<sub>2</sub> per mile",
symbol = "oz(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 1.7615576983541121e-5,
default = "gCO2/km",
link = "Exhaust gas",
},
["cuft/a"] = {
name1 = "cubic foot per annum",
name2 = "cubic feet per annum",
symbol = "cu ft/a",
utype = "flow",
scale = 8.9730672142368242e-10,
default = "m3/a",
link = "Cubic foot per second",
},
["cuft/d"] = {
name1 = "cubic foot per day",
name2 = "cubic feet per day",
symbol = "cu ft/d",
utype = "flow",
scale = 3.2774128000000003e-7,
default = "m3/d",
link = "Cubic foot per second",
},
["cuft/h"] = {
name1 = "cubic foot per hour",
name2 = "cubic feet per hour",
symbol = "cu ft/h",
utype = "flow",
scale = 7.8657907200000004e-6,
default = "m3/h",
link = "Cubic foot per second",
},
["cuft/min"] = {
name1 = "cubic foot per minute",
name2 = "cubic feet per minute",
symbol = "cu ft/min",
utype = "flow",
scale = 0.00047194744319999999,
default = "m3/min",
},
["cuft/s"] = {
name1 = "cubic foot per second",
name2 = "cubic feet per second",
symbol = "cu ft/s",
utype = "flow",
scale = 28316846592e-12,
default = "m3/s",
},
["cumi/a"] = {
name1 = "cubic mile per annum",
name2 = "cubic miles per annum",
symbol = "cu mi/a",
utype = "flow",
scale = 132.08171170940057,
default = "km3/a",
link = "Cubic foot per second",
},
["cuyd/h"] = {
name1 = "cubic yard per hour",
name2 = "cubic yards per hour",
symbol = "cuyd/h",
utype = "flow",
scale = 0.00021237634944000001,
default = "m3/h",
link = "Cubic foot per second",
},
["cuyd/s"] = {
name1 = "cubic yard per second",
name2 = "cubic yards per second",
symbol = "cu yd/s",
utype = "flow",
scale = 0.76455485798400002,
default = "m3/s",
},
["Goilbbl/a"] = {
name1 = "billion barrels per year",
name2 = "billion barrels per year",
symbol = "Gbbl/a",
utype = "flow",
scale = 5.0380033629933836,
default = "v * 1.58987294928 < 10 ! e6 ! e9 ! m3/a",
link = "Barrel per day",
},
["impgal/h"] = {
name1 = "imperial gallon per hour",
name2 = "imperial gallons per hour",
symbol = "imp gal/h",
utype = "flow",
scale = 1.2628027777777779e-6,
default = "m3/h",
link = "Gallon",
},
["impgal/min"] = {
name1 = "imperial gallon per minute",
name2 = "imperial gallons per minute",
symbol = "imp gal/min",
utype = "flow",
scale = 7.5768166666666671e-5,
default = "m3/s",
link = "Gallon",
},
["impgal/s"] = {
name1 = "imperial gallon per second",
name2 = "imperial gallons per second",
symbol = "impgal/s",
utype = "flow",
scale = 0.00454609,
default = "m3/s",
link = "Imperial gallons per second",
},
["km3/a"] = {
name1 = "cubic kilometre per annum",
name1_us = "cubic kilometer per annum",
name2 = "cubic kilometres per annum",
name2_us = "cubic kilometers per annum",
symbol = "km<sup>3</sup>/a",
utype = "flow",
scale = 31.68808781402895,
default = "cumi/a",
link = "Cubic metre per second",
},
["km3/d"] = {
name1 = "cubic kilometre per day",
name1_us = "cubic kilometer per day",
name2 = "cubic kilometres per day",
name2_us = "cubic kilometers per day",
symbol = "km<sup>3</sup>/d",
utype = "flow",
scale = 11574.074074074075,
default = "cuft/d",
link = "Cubic metre per second",
},
["koilbbl/a"] = {
name1 = "thousand barrels per year",
name2 = "thousand barrels per year",
symbol = "kbbl/a",
utype = "flow",
scale = 5.0380033629933841e-6,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3/a",
link = "Barrel per day",
},
["koilbbl/d"] = {
name1 = "thousand barrels per day",
name2 = "thousand barrels per day",
symbol = "kbbl/d",
utype = "flow",
scale = 0.0018401307283333335,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3/d",
link = "Barrel per day",
},
["L/h"] = {
name1 = "litre per hour",
name1_us = "liter per hour",
name2 = "litres per hour",
name2_us = "liters per hour",
symbol = "L/h",
utype = "flow",
scale = 2.7777777777777776e-7,
default = "impgal/h USgal/h",
link = "Cubic metre per second",
},
["L/min"] = {
name1 = "litre per minute",
name1_us = "liter per minute",
name2 = "litres per minute",
name2_us = "liters per minute",
symbol = "L/min",
utype = "flow",
scale = 1.6666666666666667e-5,
default = "impgal/min USgal/min",
link = "Cubic metre per second",
},
["L/s"] = {
name1 = "litre per second",
name1_us = "liter per second",
name2 = "litres per second",
name2_us = "liters per second",
symbol = "L/s",
utype = "flow",
scale = 0.001,
default = "cuft/s",
link = "Cubic metre per second",
},
["m3/a"] = {
name1 = "cubic metre per annum",
name1_us = "cubic meter per annum",
name2 = "cubic metres per annum",
name2_us = "cubic meters per annum",
symbol = "m<sup>3</sup>/a",
utype = "flow",
scale = 3.1688087814028947e-8,
default = "cuft/a",
link = "Cubic metre per second",
},
["m3/d"] = {
name1 = "cubic metre per day",
name1_us = "cubic meter per day",
name2 = "cubic metres per day",
name2_us = "cubic meters per day",
symbol = "m<sup>3</sup>/d",
utype = "flow",
scale = 1.1574074074074073e-5,
default = "cuft/d",
link = "Cubic metre per second",
},
["m3/h"] = {
name1 = "cubic metre per hour",
name1_us = "cubic meter per hour",
name2 = "cubic metres per hour",
name2_us = "cubic meters per hour",
symbol = "m<sup>3</sup>/h",
utype = "flow",
scale = 0.00027777777777777778,
default = "cuft/h",
link = "Cubic metre per second",
},
["m3/min"] = {
name1 = "cubic metre per minute",
name1_us = "cubic meter per minute",
name2 = "cubic metres per minute",
name2_us = "cubic meters per minute",
symbol = "m<sup>3</sup>/min",
utype = "flow",
scale = 0.016666666666666666,
default = "cuft/min",
link = "Cubic metre per second",
},
["m3/s"] = {
name1 = "cubic metre per second",
name1_us = "cubic meter per second",
name2 = "cubic metres per second",
name2_us = "cubic meters per second",
symbol = "m<sup>3</sup>/s",
utype = "flow",
scale = 1,
default = "cuft/s",
},
["Moilbbl/a"] = {
name1 = "million barrels per year",
name2 = "million barrels per year",
symbol = "Mbbl/a",
utype = "flow",
scale = 0.0050380033629933837,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3/a",
link = "Barrel per day",
},
["Moilbbl/d"] = {
name1 = "million barrels per day",
name2 = "million barrels per day",
symbol = "Mbbl/d",
utype = "flow",
scale = 1.8401307283333335,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3/d",
link = "Barrel per day",
},
["oilbbl/a"] = {
name1 = "barrel per year",
name2 = "barrels per year",
symbol = "bbl/a",
utype = "flow",
scale = 5.0380033629933841e-9,
default = "m3/a",
link = "Barrel per day",
},
["oilbbl/d"] = {
name1 = "barrel per day",
name2 = "barrels per day",
symbol = "bbl/d",
utype = "flow",
scale = 1.8401307283333336e-6,
default = "m3/d",
},
["Toilbbl/a"] = {
name1 = "trillion barrels per year",
name2 = "trillion barrels per year",
symbol = "Tbbl/a",
utype = "flow",
scale = 5038.0033629933832,
default = "v * 1.58987294928 < 10 ! e9 ! e12 ! m3/a",
link = "Barrel per day",
},
["U.S.gal/d"] = {
name1 = "U.S. gallon per day",
name2 = "U.S. gallons per day",
symbol = "U.S. gal/d",
utype = "flow",
scale = 4.3812636388888893e-8,
default = "m3/s",
customary= 1,
},
["U.S.gal/h"] = {
name1 = "gallon per hour",
name2 = "gallons per hour",
symbol = "gal/h",
utype = "flow",
scale = 1.0515032733333334e-6,
default = "m3/h",
link = "Gallon",
customary= 2,
},
["U.S.gal/min"] = {
name1 = "U.S. gallon per minute",
name2 = "U.S. gallons per minute",
symbol = "U.S. gal/min",
utype = "flow",
scale = 6.3090196400000003e-5,
default = "m3/s",
link = "Gallon",
},
["USgal/a"] = {
name1 = "US gallon per year",
name2 = "US gallons per year",
symbol = "US gal/a",
utype = "flow",
scale = 1.1995246102365199e-10,
default = "m3/s",
},
["USgal/d"] = {
name1 = "US gallon per day",
name2 = "US gallons per day",
symbol = "US gal/d",
utype = "flow",
scale = 4.3812636388888893e-8,
default = "m3/s",
},
["USgal/h"] = {
name1 = "gallon per hour",
name2 = "gallons per hour",
symbol = "gal/h",
utype = "flow",
scale = 1.0515032733333334e-6,
default = "m3/h",
link = "Gallon",
customary= 1,
},
["USgal/min"] = {
name1 = "US gallon per minute",
name2 = "US gallons per minute",
symbol = "US gal/min",
utype = "flow",
scale = 6.3090196400000003e-5,
default = "m3/s",
link = "Gallon",
},
["USgal/s"] = {
name1 = "US gallon per second",
name1_us = "U.S. gallon per second",
name2 = "US gallons per second",
name2_us = "U.S. gallons per second",
symbol = "USgal/s",
utype = "flow",
scale = 0.003785411784,
default = "m3/s",
link = "US gallons per second",
},
["ft3/a"] = {
target = "cuft/a",
},
["ft3/d"] = {
target = "cuft/d",
},
["ft3/h"] = {
target = "cuft/h",
},
["ft3/s"] = {
target = "cuft/s",
},
["Gcuft/a"] = {
target = "e9cuft/a",
},
["Gcuft/d"] = {
target = "e9cuft/d",
},
["kcuft/a"] = {
target = "e3cuft/a",
},
["kcuft/d"] = {
target = "e3cuft/d",
},
["kcuft/s"] = {
target = "e3cuft/s",
},
["Mcuft/a"] = {
target = "e6cuft/a",
},
["Mcuft/d"] = {
target = "e6cuft/d",
},
["Mcuft/s"] = {
target = "e6cuft/s",
},
["m³/s"] = {
target = "m3/s",
},
["Tcuft/a"] = {
target = "e12cuft/a",
},
["Tcuft/d"] = {
target = "e12cuft/d",
},
["u.s.gal/min"] = {
target = "U.S.gal/min",
},
["usgal/min"] = {
target = "USgal/min",
},
["-LTf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LTf",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["-STf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "STf",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["dyn"] = {
name1 = "dyne",
symbol = "dyn",
utype = "force",
scale = 0.00001,
default = "gr-f",
},
["g-f"] = {
name1 = "gram-force",
name2 = "grams-force",
symbol = "g<sub>f</sub>",
utype = "force",
scale = 0.00980665,
default = "mN oz-f",
link = "Kilogram-force",
},
["gf"] = {
name1 = "gram-force",
name2 = "grams-force",
symbol = "gf",
utype = "force",
scale = 0.00980665,
default = "mN ozf",
link = "Kilogram-force",
},
["gr-f"] = {
name1 = "grain-force",
name2 = "grains-force",
symbol = "gr<sub>f</sub>",
utype = "force",
scale = 0.0006354602307515,
default = "μN",
link = "Pound (force)",
},
["grf"] = {
name1 = "grain-force",
name2 = "grains-force",
symbol = "grf",
utype = "force",
scale = 0.0006354602307515,
default = "μN",
link = "Pound (force)",
},
["kdyn"] = {
name1 = "kilodyne",
symbol = "kdyn",
utype = "force",
scale = 0.01,
default = "oz-f",
link = "Dyne",
},
["kg-f"] = {
name1 = "kilogram-force",
name2 = "kilograms-force",
symbol = "kg<sub>f</sub>",
utype = "force",
scale = 9.80665,
default = "N lb-f",
},
["kgf"] = {
name1 = "kilogram-force",
name2 = "kilograms-force",
symbol = "kgf",
utype = "force",
scale = 9.80665,
default = "N lbf",
},
["kp"] = {
name1 = "kilopond",
symbol = "kp",
utype = "force",
scale = 9.80665,
default = "N lb-f",
link = "Kilogram-force",
},
["L/T-f"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "L/T<sub>f</sub>",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["L/Tf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "L/Tf",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["lb-f"] = {
name1 = "pound-force",
name2 = "pounds-force",
symbol = "lb<sub>f</sub>",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["lbf"] = {
name1 = "pound-force",
name2 = "pounds-force",
symbol = "lbf",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["lb(f)"] = {
name1 = "pound",
symbol = "lb",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["LT-f"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LT<sub>f</sub>",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["LTf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LTf",
usename = 1,
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["Mdyn"] = {
name1 = "megadyne",
symbol = "Mdyn",
utype = "force",
scale = 10,
default = "lb-f",
link = "Dyne",
},
["mdyn"] = {
name1 = "millidyne",
symbol = "mdyn",
utype = "force",
scale = 0.00000001,
default = "gr-f",
link = "Dyne",
},
["mg-f"] = {
name1 = "milligram-force",
name2 = "milligrams-force",
symbol = "mg<sub>f</sub>",
utype = "force",
scale = 0.00000980665,
default = "μN gr-f",
link = "Kilogram-force",
},
["mgf"] = {
name1 = "milligram-force",
name2 = "milligrams-force",
symbol = "mgf",
utype = "force",
scale = 0.00000980665,
default = "μN grf",
link = "Kilogram-force",
},
["Mp"] = {
name1 = "megapond",
symbol = "Mp",
utype = "force",
scale = 9806.65,
default = "kN LT-f ST-f",
link = "Kilogram-force",
},
["mp"] = {
name1 = "millipond",
symbol = "mp",
utype = "force",
scale = 0.00000980665,
default = "μN gr-f",
link = "Kilogram-force",
},
["N"] = {
_name1 = "newton",
_symbol = "N",
utype = "force",
scale = 1,
prefixes = 1,
default = "lb-f",
link = "Newton (unit)",
},
["oz-f"] = {
name1 = "ounce-force",
name2 = "ounces-force",
symbol = "oz<sub>f</sub>",
utype = "force",
scale = 0.2780138203095378125,
default = "mN",
link = "Pound (force)",
},
["ozf"] = {
name1 = "ounce-force",
name2 = "ounces-force",
symbol = "ozf",
utype = "force",
scale = 0.2780138203095378125,
default = "mN",
link = "Pound (force)",
},
["p"] = {
name1 = "pond",
symbol = "p",
utype = "force",
scale = 0.00980665,
default = "mN oz-f",
link = "Kilogram-force",
},
["pdl"] = {
name1 = "poundal",
symbol = "pdl",
utype = "force",
scale = 0.138254954376,
default = "N",
},
["S/T-f"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "S/T<sub>f</sub>",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["S/Tf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "S/Tf",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["ST-f"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "ST<sub>f</sub>",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["STf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "STf",
usename = 1,
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["t-f"] = {
name1 = "tonne-force",
name2 = "tonnes-force",
symbol = "t<sub>f</sub>",
utype = "force",
scale = 9806.65,
default = "kN LT-f ST-f",
link = "Ton-force#Tonne-force",
},
["tf"] = {
name1 = "tonne-force",
name2 = "tonnes-force",
symbol = "tf",
utype = "force",
scale = 9806.65,
default = "kN LTf STf",
link = "Ton-force#Tonne-force",
},
["dyne"] = {
target = "dyn",
},
["newtons"] = {
target = "N",
},
["poundal"] = {
target = "pdl",
},
["tonne-force"] = {
target = "tf",
},
["impgal/mi"] = {
per = { "@impgal", "mi" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km USgal/mi",
},
["km/L"] = {
per = { "km", "L" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "mpgimp mpgus",
},
["km/l"] = {
per = { "km", "l" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "mpgimp mpgus",
},
["L/100 km"] = {
per = { "L", "100km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|L/100 km]]",
},
["l/100 km"] = {
per = { "l", "100km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|l/100 km]]",
},
["L/km"] = {
per = { "L", "km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
},
["l/km"] = {
per = { "l", "km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
},
["mi/impqt"] = {
per = { "mi", "impqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/U.S.qt"] = {
per = { "mi", "U.S.qt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/USqt"] = {
per = { "mi", "USqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/usqt"] = {
per = { "mi", "usqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mpgimp"] = {
per = { "mi", "@impgal" },
symbol = "mpg<sub>‑imp</sub>",
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "L/100 km+mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[Imperial units|imp]]</sub>",
},
["mpgus"] = {
per = { "mi", "+USgal" },
symbol = "mpg<sub>‑US</sub>",
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "L/100 km+mpgimp",
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|US]]</sub>",
},
["U.S.gal/mi"] = {
per = { "*U.S.gal", "mi" },
sp_us = true,
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km impgal/mi",
},
["usgal/mi"] = {
per = { "+USgal", "mi" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km impgal/mi",
},
["L/100km"] = {
target = "L/100 km",
},
["l/100km"] = {
target = "l/100 km",
},
["mpg"] = {
shouldbe = "Use %{mpgus%} for miles per US gallon or %{mpgimp%} for miles per imperial gallon (not %{mpg%})",
},
["mpgU.S."] = {
target = "mpgus",
symbol = "mpg<sub>‑U.S.</sub>",
sp_us = true,
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|U.S.]]</sub>",
},
["mpgu.s."] = {
target = "mpgus",
symbol = "mpg<sub>‑U.S.</sub>",
sp_us = true,
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|U.S.]]</sub>",
},
["mpgUS"] = {
target = "mpgus",
},
["USgal/mi"] = {
target = "usgal/mi",
},
["kPa/m"] = {
per = { "kPa", "-m-frac" },
utype = "fracture gradient",
default = "psi/ft",
},
["psi/ft"] = {
per = { "psi", "-ft-frac" },
utype = "fracture gradient",
default = "kPa/m",
},
["cm/km"] = {
name1 = "centimetre per kilometre",
name1_us = "centimeter per kilometer",
name2 = "centimetres per kilometre",
name2_us = "centimeters per kilometer",
symbol = "cm/km",
utype = "gradient",
scale = 0.00001,
default = "ft/mi",
link = "Grade (slope)",
},
["ft/mi"] = {
name1 = "foot per mile",
name2 = "feet per mile",
symbol = "ft/mi",
utype = "gradient",
scale = 0.00018939393939393939,
default = "v < 5.28 ! c ! ! m/km",
link = "Grade (slope)",
},
["ft/nmi"] = {
name1 = "foot per nautical mile",
name2 = "feet per nautical mile",
symbol = "ft/nmi",
utype = "gradient",
scale = 0.00016457883369330455,
default = "v < 6.076 ! c ! ! m/km",
link = "Grade (slope)",
},
["in/ft"] = {
name1 = "inch per foot",
name2 = "inches per foot",
symbol = "in/ft",
utype = "gradient",
scale = 0.083333333333333329,
default = "mm/m",
link = "Grade (slope)",
},
["in/mi"] = {
name1 = "inch per mile",
name2 = "inches per mile",
symbol = "in/mi",
utype = "gradient",
scale = 1.5782828282828283e-5,
default = "v < 0.6336 ! m ! c ! m/km",
link = "Grade (slope)",
},
["m/km"] = {
name1 = "metre per kilometre",
name1_us = "meter per kilometer",
name2 = "metres per kilometre",
name2_us = "meters per kilometer",
symbol = "m/km",
utype = "gradient",
scale = 0.001,
default = "ft/mi",
link = "Grade (slope)",
},
["mm/km"] = {
name1 = "millimetre per kilometre",
name1_us = "millimeter per kilometer",
name2 = "millimetres per kilometre",
name2_us = "millimeters per kilometer",
symbol = "mm/km",
utype = "gradient",
scale = 0.000001,
default = "in/mi",
link = "Grade (slope)",
},
["mm/m"] = {
name1 = "millimetre per metre",
name1_us = "millimeter per meter",
name2 = "millimetres per metre",
name2_us = "millimeters per meter",
symbol = "mm/m",
utype = "gradient",
scale = 0.001,
default = "in/ft",
link = "Grade (slope)",
},
["admi"] = {
name1 = "admiralty mile",
symbol = "nmi (admiralty)",
utype = "length",
scale = 1853.184,
default = "km mi",
link = "Nautical mile",
},
["AU"] = {
name1 = "astronomical unit",
symbol = "AU",
utype = "length",
scale = 149597870700,
default = "km mi",
},
["Brnmi"] = {
name1 = "British nautical mile",
symbol = "(Brit) nmi",
utype = "length",
scale = 1853.184,
default = "km mi",
link = "Nautical mile",
},
["bu"] = {
name2 = "bu",
symbol = "bu",
usename = 1,
utype = "length",
scale = 0.0030303030303030303,
default = "mm",
link = "Japanese units of measurement#Length",
},
["ch"] = {
name1 = "chain",
symbol = "ch",
utype = "length",
scale = 20.1168,
default = "ft m",
subdivs = { ["ft"] = { 66, default = "m" }, ["yd"] = { 22, default = "m" } },
link = "Chain (unit)",
},
["chlk"] = {
name1 = "[[Chain (unit)|chain]]",
symbol = "[[Chain (unit)|ch]]",
utype = "length",
scale = 20.1168,
default = "ft m",
link = "",
},
["chain"] = {
symbol = "chain",
usename = 1,
utype = "length",
scale = 20.1168,
default = "ft m",
subdivs = { ["ft"] = { 66, default = "m" }, ["yd"] = { 22, default = "m" } },
link = "Chain (unit)",
},
["chainlk"] = {
symbol = "[[Chain (unit)|chain]]",
usename = 1,
utype = "length",
scale = 20.1168,
default = "ft m",
link = "",
},
["dpcm"] = {
name2 = "dot/cm",
symbol = "dot/cm",
utype = "length",
scale = 100,
invert = -1,
iscomplex= true,
default = "dpi",
link = "Dots per inch",
},
["dpi"] = {
name2 = "DPI",
symbol = "DPI",
utype = "length",
scale = 39.370078740157481,
invert = -1,
iscomplex= true,
default = "pitch",
link = "Dots per inch",
},
["fathom"] = {
symbol = "fathom",
usename = 1,
utype = "length",
scale = 1.8288,
default = "ft m",
},
["foot"] = {
name1 = "foot",
name2 = "foot",
symbol = "ft",
utype = "length",
scale = 0.3048,
default = "m",
subdivs = { ["in"] = { 12, default = "m" } },
link = "Foot (unit)",
},
["ft"] = {
name1 = "foot",
name2 = "feet",
symbol = "ft",
utype = "length",
scale = 0.3048,
exception= "integer_more_precision",
default = "m",
subdivs = { ["in"] = { 12, default = "m" } },
link = "Foot (unit)",
},
["furlong"] = {
symbol = "furlong",
usename = 1,
utype = "length",
scale = 201.168,
default = "ft m",
},
["Gly"] = {
name1 = "gigalight-year",
symbol = "Gly",
utype = "length",
scale = 9.4607304725808e24,
default = "Mpc",
link = "Light-year#Definitions",
},
["Gpc"] = {
name1 = "gigaparsec",
symbol = "Gpc",
utype = "length",
scale = 3.0856775814671916e25,
default = "Gly",
link = "Parsec#Megaparsecs and gigaparsecs",
},
["hand"] = {
name1 = "hand",
symbol = "h",
utype = "length",
builtin = "hand",
scale = 0.1016,
iscomplex= true,
default = "in cm",
link = "Hand (unit)",
},
["in"] = {
name1 = "inch",
name2 = "inches",
symbol = "in",
utype = "length",
scale = 0.0254,
exception= "subunit_more_precision",
default = "mm",
},
["inabbreviated"] = {
name2 = "in",
symbol = "in",
utype = "length",
scale = 0.0254,
default = "mm",
link = "Inch",
},
["kly"] = {
name1 = "kilolight-year",
symbol = "kly",
utype = "length",
scale = 9.4607304725808e18,
default = "pc",
link = "Light-year#Definitions",
},
["kpc"] = {
name1 = "kiloparsec",
symbol = "kpc",
utype = "length",
scale = 3.0856775814671916e19,
default = "kly",
link = "Parsec#Parsecs and kiloparsecs",
},
["LD"] = {
name1 = "lunar distance",
symbol = "LD",
utype = "length",
scale = 384403000,
default = "km mi",
link = "Lunar distance (astronomy)",
},
["league"] = {
symbol = "league",
usename = 1,
utype = "length",
scale = 4828.032,
default = "km",
link = "League (unit)",
},
["ly"] = {
name1 = "light-year",
symbol = "ly",
utype = "length",
scale = 9.4607304725808e15,
default = "AU",
},
["m"] = {
_name1 = "metre",
_name1_us= "meter",
_symbol = "m",
utype = "length",
scale = 1,
prefixes = 1,
default = "v > 0 and v < 3 ! ftin ! ft",
link = "Metre",
},
["mi"] = {
name1 = "mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
subdivs = { ["ch"] = { 80, default = "km" }, ["chlk"] = { 80, default = "km" }, ["chain"] = { 80, default = "km" }, ["chainlk"] = { 80, default = "km" }, ["ft"] = { 5280, default = "km" }, ["furlong"] = { 8, default = "km" }, ["yd"] = { 1760, default = "km" } },
},
["mil"] = {
symbol = "mil",
usename = 1,
utype = "length",
scale = 0.0000254,
default = "mm",
link = "Thousandth of an inch",
},
["Mly"] = {
name1 = "megalight-year",
symbol = "Mly",
utype = "length",
scale = 9.4607304725808e21,
default = "kpc",
link = "Light-year#Definitions",
},
["Mpc"] = {
name1 = "megaparsec",
symbol = "Mpc",
utype = "length",
scale = 3.0856775814671916e22,
default = "Mly",
link = "Parsec#Megaparsecs and gigaparsecs",
},
["NM"] = {
name1 = "nautical mile",
symbol = "NM",
utype = "length",
scale = 1852,
default = "km mi",
},
["nmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1852,
default = "km mi",
},
["oldUKnmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1853.184,
default = "km mi",
},
["oldUSnmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
},
["pc"] = {
name1 = "parsec",
symbol = "pc",
utype = "length",
scale = 3.0856775814671916e16,
default = "ly",
},
["perch"] = {
name2 = "perches",
symbol = "perch",
usename = 1,
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["pitch"] = {
name2 = "μm",
symbol = "μm",
utype = "length",
scale = 1e-6,
default = "dpi",
defkey = "pitch",
linkey = "pitch",
link = "Dots per inch",
},
["pole"] = {
symbol = "pole",
usename = 1,
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["pre1954U.S.nmi"] = {
name1 = "(pre-1954 U.S.) nautical mile",
symbol = "(pre‑1954 U.S.) nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
link = "Nautical mile",
},
["pre1954USnmi"] = {
name1 = "(pre-1954 US) nautical mile",
name1_us = "(pre-1954 U.S.) nautical mile",
symbol = "(pre‑1954 US) nmi",
sym_us = "(pre‑1954 U.S.) nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
link = "Nautical mile",
},
["rd"] = {
name1 = "rod",
symbol = "rd",
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["royal cubit"] = {
name1 = "royal cubit",
symbol = "cu",
utype = "length",
scale = 0.524,
default = "mm",
},
["rtkm"] = {
name1 = "route kilometre",
name1_us = "route kilometer",
symbol = "km",
utype = "length",
scale = 1000,
default = "mi",
link = "Kilometre",
},
["rtmi"] = {
name1 = "route mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
link = "Mile",
},
["shaku"] = {
name2 = "shaku",
symbol = "shaku",
usename = 1,
utype = "length",
scale = 0.30303030303030304,
default = "m",
link = "Shaku (unit)",
},
["sm"] = {
name1 = "smoot",
symbol = "sm",
utype = "length",
scale = 1.70180,
default = "m",
link = "Smoot (unit)",
},
["smi"] = {
name1 = "statute mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
subdivs = { ["chain"] = { 80, default = "km" } },
},
["solar radius"] = {
name1 = "solar radius",
name2 = "solar radii",
symbol = "''R''<sub>☉</sub>",
utype = "length",
scale = 695700e3,
default = "km",
},
["sun"] = {
name2 = "sun",
symbol = "sun",
usename = 1,
utype = "length",
scale = 0.030303030303030304,
default = "mm",
link = "Japanese units of measurement#Length",
},
["thou"] = {
name2 = "thou",
symbol = "thou",
usename = 1,
utype = "length",
scale = 0.0000254,
default = "mm",
link = "Thousandth of an inch",
},
["verst"] = {
symbol = "verst",
usename = 1,
utype = "length",
scale = 1066.8,
default = "km mi",
},
["yd"] = {
name1 = "yard",
symbol = "yd",
utype = "length",
scale = 0.9144,
default = "m",
subdivs = { ["ft"] = { 3, default = "m" } },
},
["μin"] = {
name1 = "microinch",
name2 = "microinches",
symbol = "μin",
utype = "length",
scale = 0.0000000254,
default = "nm",
link = "SI prefix#Non-metric units",
},
["Å"] = {
name1 = "ångström",
symbol = "Å",
utype = "length",
scale = 0.0000000001,
default = "in",
},
["Hz"] = {
_name1 = "hertz",
_name2 = "hertz",
_symbol = "Hz",
utype = "length",
scale = 3.3356409519815204e-9,
invert = -1,
iscomplex= true,
prefixes = 1,
default = "m",
link = "Hertz",
},
["rpm"] = {
name1 = "revolution per minute",
name2 = "revolutions per minute",
symbol = "rpm",
utype = "length",
scale = 5.5594015866358675e-11,
invert = -1,
iscomplex= true,
default = "Hz",
link = "Revolutions per minute",
},
["-ft-frac"] = {
target = "ft",
link = "Fracture gradient",
},
["-in-stiff"] = {
target = "in",
link = "Stiffness",
},
["-m-frac"] = {
target = "m",
link = "Fracture gradient",
},
["-m-stiff"] = {
target = "m",
link = "Stiffness",
},
["100km"] = {
target = "km",
multiplier= 100,
},
["100mi"] = {
target = "mi",
multiplier= 100,
},
["100miles"] = {
target = "mi",
symbol = "miles",
multiplier= 100,
},
["admiralty nmi"] = {
target = "oldUKnmi",
},
["angstrom"] = {
target = "Å",
},
["au"] = {
target = "AU",
symbol = "au",
},
["feet"] = {
target = "ft",
},
["hands"] = {
target = "hand",
},
["inch"] = {
target = "in",
},
["light-year"] = {
target = "ly",
},
["meter"] = {
target = "m",
sp_us = true,
},
["meters"] = {
target = "m",
sp_us = true,
},
["metre"] = {
target = "m",
},
["metres"] = {
target = "m",
},
["micrometre"] = {
target = "μm",
},
["micron"] = {
target = "μm",
default = "μin",
},
["mile"] = {
target = "mi",
},
["miles"] = {
target = "mi",
},
["parsec"] = {
target = "pc",
},
["rod"] = {
target = "rd",
},
["smoot"] = {
target = "sm",
},
["uin"] = {
target = "μin",
},
["yard"] = {
target = "yd",
},
["yards"] = {
target = "yd",
},
["yds"] = {
target = "yd",
},
["dtex"] = {
name1 = "decitex",
name2 = "decitex",
symbol = "dtex",
utype = "linear density",
scale = 1e-7,
default = "lb/yd",
link = "Units of textile measurement#Units",
},
["kg/cm"] = {
name1 = "kilogram per centimetre",
name1_us = "kilogram per centimeter",
name2 = "kilograms per centimetre",
name2_us = "kilograms per centimeter",
symbol = "kg/cm",
utype = "linear density",
scale = 100,
default = "lb/yd",
link = "Linear density",
},
["kg/m"] = {
name1 = "kilogram per metre",
name1_us = "kilogram per meter",
name2 = "kilograms per metre",
name2_us = "kilograms per meter",
symbol = "kg/m",
utype = "linear density",
scale = 1,
default = "lb/yd",
link = "Linear density",
},
["lb/ft"] = {
name1 = "pound per foot",
name2 = "pounds per foot",
symbol = "lb/ft",
utype = "linear density",
scale = 1.4881639435695539,
default = "kg/m",
link = "Linear density",
},
["lb/yd"] = {
name1 = "pound per yard",
name2 = "pounds per yard",
symbol = "lb/yd",
utype = "linear density",
scale = 0.49605464785651798,
default = "kg/m",
link = "Linear density",
},
["G"] = {
_name1 = "gauss",
_name2 = "gauss",
_symbol = "G",
utype = "magnetic field strength",
scale = 0.0001,
prefixes = 1,
default = "T",
link = "Gauss (unit)",
},
["T"] = {
_name1 = "tesla",
_symbol = "T",
utype = "magnetic field strength",
scale = 1,
prefixes = 1,
default = "G",
link = "Tesla (unit)",
},
["A/m"] = {
name1 = "ampere per metre",
name1_us = "ampere per meter",
name2 = "amperes per metre",
name2_us = "amperes per meter",
symbol = "A/m",
utype = "magnetizing field",
scale = 1,
default = "Oe",
},
["kA/m"] = {
name1 = "kiloampere per metre",
name1_us = "kiloampere per meter",
name2 = "kiloamperes per metre",
name2_us = "kiloamperes per meter",
symbol = "kA/m",
utype = "magnetizing field",
scale = 1000,
default = "kOe",
link = "Ampere per metre",
},
["MA/m"] = {
name1 = "megaampere per metre",
name1_us = "megaampere per meter",
name2 = "megaamperes per metre",
name2_us = "megaamperes per meter",
symbol = "MA/m",
utype = "magnetizing field",
scale = 1e6,
default = "kOe",
link = "Ampere per metre",
},
["Oe"] = {
_name1 = "oersted",
_symbol = "Oe",
utype = "magnetizing field",
scale = 79.5774715,
prefixes = 1,
default = "kA/m",
link = "Oersted",
},
["-Lcwt"] = {
name1 = "hundredweight",
name2 = "hundredweight",
symbol = "cwt",
utype = "mass",
scale = 50.80234544,
default = "lb",
},
["-Scwt"] = {
name1 = "hundredweight",
name2 = "hundredweight",
symbol = "cwt",
utype = "mass",
scale = 45.359237,
default = "lb",
},
["-ST"] = {
name1 = "short ton",
symbol = "ST",
utype = "mass",
scale = 907.18474,
default = "t",
},
["carat"] = {
symbol = "carat",
usename = 1,
utype = "mass",
scale = 0.0002,
default = "g",
link = "Carat (mass)",
},
["drachm"] = {
name1_us = "dram",
symbol = "drachm",
usename = 1,
utype = "mass",
scale = 0.001771845195,
default = "g",
link = "Dram (unit)",
},
["dram"] = {
target = "drachm",
},
["dwt"] = {
name1 = "pennyweight",
symbol = "dwt",
utype = "mass",
scale = 0.00155517384,
default = "oz g",
},
["DWton"] = {
symbol = "deadweight ton",
usename = 1,
utype = "mass",
scale = 1016.0469088,
default = "DWtonne",
link = "Deadweight tonnage",
},
["DWtonne"] = {
symbol = "deadweight tonne",
usename = 1,
utype = "mass",
scale = 1000,
default = "DWton",
link = "Deadweight tonnage",
},
["g"] = {
_name1 = "gram",
_symbol = "g",
utype = "mass",
scale = 0.001,
prefixes = 1,
default = "oz",
link = "Gram",
},
["gr"] = {
name1 = "grain",
symbol = "gr",
utype = "mass",
scale = 0.00006479891,
default = "g",
link = "Grain (unit)",
},
["Gt"] = {
name1 = "gigatonne",
symbol = "Gt",
utype = "mass",
scale = 1000000000000,
default = "LT ST",
link = "Tonne",
},
["impgalh2o"] = {
name1 = "imperial gallon of water",
name2 = "imperial gallons of water",
symbol = "imp gal H<sub>2</sub>O",
utype = "mass",
scale = 4.5359236999999499,
default = "lb kg",
link = "Imperial gallon",
},
["kt"] = {
name1 = "kilotonne",
symbol = "kt",
utype = "mass",
scale = 1000000,
default = "LT ST",
link = "Tonne",
},
["lb"] = {
name1 = "pound",
symbol = "lb",
utype = "mass",
scale = 0.45359237,
exception= "integer_more_precision",
default = "kg",
subdivs = { ["oz"] = { 16, default = "kg" } },
link = "Pound (mass)",
},
["Lcwt"] = {
name1 = "long hundredweight",
name2 = "long hundredweight",
symbol = "Lcwt",
usename = 1,
utype = "mass",
scale = 50.80234544,
default = "lb",
subdivs = { ["qtr"] = { 4, default = "kg" }, ["st"] = { 8, default = "kg" } },
link = "Hundredweight",
},
["long cwt"] = {
name1 = "long hundredweight",
name2 = "long hundredweight",
symbol = "long cwt",
utype = "mass",
scale = 50.80234544,
default = "lb kg",
subdivs = { ["qtr"] = { 4, default = "kg" } },
link = "Hundredweight",
},
["long qtr"] = {
name1 = "long quarter",
symbol = "long qtr",
utype = "mass",
scale = 12.70058636,
default = "lb kg",
},
["LT"] = {
symbol = "long ton",
usename = 1,
utype = "mass",
scale = 1016.0469088,
default = "t",
subdivs = { ["Lcwt"] = { 20, default = "t", unit = "-Lcwt" } },
},
["lt"] = {
name1 = "long ton",
symbol = "LT",
utype = "mass",
scale = 1016.0469088,
default = "t",
subdivs = { ["Lcwt"] = { 20, default = "t", unit = "-Lcwt" } },
},
["metric ton"] = {
symbol = "metric ton",
usename = 1,
utype = "mass",
scale = 1000,
default = "long ton",
link = "Tonne",
},
["MT"] = {
name1 = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "LT ST",
link = "Tonne",
},
["Mt"] = {
name1 = "megatonne",
symbol = "Mt",
utype = "mass",
scale = 1000000000,
default = "LT ST",
link = "Tonne",
},
["oz"] = {
name1 = "ounce",
symbol = "oz",
utype = "mass",
scale = 0.028349523125,
default = "g",
},
["ozt"] = {
name1 = "troy ounce",
symbol = "ozt",
utype = "mass",
scale = 0.0311034768,
default = "oz g",
},
["pdr"] = {
name1 = "pounder",
symbol = "pdr",
utype = "mass",
scale = 0.45359237,
default = "kg",
link = "Pound (mass)",
},
["qtr"] = {
name1 = "quarter",
symbol = "qtr",
utype = "mass",
scale = 12.70058636,
default = "lb kg",
subdivs = { ["lb"] = { 28, default = "kg" } },
link = "Long quarter",
},
["Scwt"] = {
name1 = "short hundredweight",
name2 = "short hundredweight",
symbol = "Scwt",
usename = 1,
utype = "mass",
scale = 45.359237,
default = "lb",
link = "Hundredweight",
},
["short cwt"] = {
name1 = "short hundredweight",
name2 = "short hundredweight",
symbol = "short cwt",
utype = "mass",
scale = 45.359237,
default = "lb kg",
link = "Hundredweight",
},
["short qtr"] = {
name1 = "short quarter",
symbol = "short qtr",
utype = "mass",
scale = 11.33980925,
default = "lb kg",
},
["ST"] = {
symbol = "short ton",
usename = 1,
utype = "mass",
scale = 907.18474,
default = "t",
subdivs = { ["Scwt"] = { 20, default = "t", unit = "-Scwt" } },
},
["shtn"] = {
name1 = "short ton",
symbol = "sh tn",
utype = "mass",
scale = 907.18474,
default = "t",
},
["shton"] = {
symbol = "ton",
usename = 1,
utype = "mass",
scale = 907.18474,
default = "t",
},
["solar mass"] = {
name1 = "solar mass",
name2 = "solar masses",
symbol = "''M''<sub>☉</sub>",
utype = "mass",
scale = 1.98855e30,
default = "kg",
},
["st"] = {
name1 = "stone",
name2 = "stone",
symbol = "st",
utype = "mass",
scale = 6.35029318,
default = "lb kg",
subdivs = { ["lb"] = { 14, default = "kg lb" } },
link = "Stone (unit)",
},
["t"] = {
name1 = "tonne",
name1_us = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "LT ST",
},
["tonne"] = {
name1 = "tonne",
name1_us = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "shton",
},
["troy pound"] = {
symbol = "troy pound",
usename = 1,
utype = "mass",
scale = 0.3732417216,
default = "lb kg",
link = "Troy weight",
},
["usgalh2o"] = {
name1 = "US gallon of water",
name1_us = "U.S. gallon of water",
name2 = "US gallons of water",
name2_us = "U.S. gallons of water",
symbol = "US gal H<sub>2</sub>O",
utype = "mass",
scale = 3.7776215836051126,
default = "lb kg",
link = "United States customary units#Fluid volume",
},
["viss"] = {
name2 = "viss",
symbol = "viss",
utype = "mass",
scale = 1.632932532,
default = "kg",
link = "Myanmar units of measurement#Mass",
},
["billion tonne"] = {
target = "e9t",
},
["kilogram"] = {
target = "kg",
},
["kilotonne"] = {
target = "kt",
},
["lbs"] = {
target = "lb",
},
["lbt"] = {
target = "troy pound",
},
["lcwt"] = {
target = "Lcwt",
},
["long ton"] = {
target = "LT",
},
["mcg"] = {
target = "μg",
},
["million tonne"] = {
target = "e6t",
},
["scwt"] = {
target = "Scwt",
},
["short ton"] = {
target = "ST",
},
["stone"] = {
target = "st",
},
["thousand tonne"] = {
target = "e3t",
},
["tonnes"] = {
target = "t",
},
["kg/kW"] = {
name1 = "kilogram per kilowatt",
name2 = "kilograms per kilowatt",
symbol = "kg/kW",
utype = "mass per unit power",
scale = 0.001,
default = "lb/hp",
link = "Kilowatt",
},
["lb/hp"] = {
name1 = "pound per horsepower",
name2 = "pounds per horsepower",
symbol = "lb/hp",
utype = "mass per unit power",
scale = 0.00060827738784176115,
default = "kg/kW",
link = "Horsepower",
},
["kg/h"] = {
per = { "kg", "h" },
utype = "mass per unit time",
default = "lb/h",
},
["lb/h"] = {
per = { "lb", "h" },
utype = "mass per unit time",
default = "kg/h",
},
["g-mol/d"] = {
name1 = "gram-mole per day",
name2 = "gram-moles per day",
symbol = "g‑mol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["g-mol/h"] = {
name1 = "gram-mole per hour",
name2 = "gram-moles per hour",
symbol = "g‑mol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["g-mol/min"] = {
name1 = "gram-mole per minute",
name2 = "gram-moles per minute",
symbol = "g‑mol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "g-mol/s",
link = "Mole (unit)",
},
["g-mol/s"] = {
name1 = "gram-mole per second",
name2 = "gram-moles per second",
symbol = "g‑mol/s",
utype = "molar rate",
scale = 1,
default = "lb-mol/min",
link = "Mole (unit)",
},
["gmol/d"] = {
name1 = "gram-mole per day",
name2 = "gram-moles per day",
symbol = "gmol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["gmol/h"] = {
name1 = "gram-mole per hour",
name2 = "gram-moles per hour",
symbol = "gmol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["gmol/min"] = {
name1 = "gram-mole per minute",
name2 = "gram-moles per minute",
symbol = "gmol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "gmol/s",
link = "Mole (unit)",
},
["gmol/s"] = {
name1 = "gram-mole per second",
name2 = "gram-moles per second",
symbol = "gmol/s",
utype = "molar rate",
scale = 1,
default = "lbmol/min",
link = "Mole (unit)",
},
["kmol/d"] = {
name1 = "kilomole per day",
name2 = "kilomoles per day",
symbol = "kmol/d",
utype = "molar rate",
scale = 0.011574074074074073,
default = "mmol/s",
link = "Mole (unit)",
},
["kmol/h"] = {
name1 = "kilomole per hour",
name2 = "kilomoles per hour",
symbol = "kmol/h",
utype = "molar rate",
scale = 0.27777777777777779,
default = "mol/s",
link = "Mole (unit)",
},
["kmol/min"] = {
name1 = "kilomole per minute",
name2 = "kilomoles per minute",
symbol = "kmol/min",
utype = "molar rate",
scale = 16.666666666666668,
default = "mol/s",
link = "Kilomole (unit)",
},
["kmol/s"] = {
name1 = "kilomole per second",
name2 = "kilomoles per second",
symbol = "kmol/s",
utype = "molar rate",
scale = 1000,
default = "lb-mol/s",
link = "Mole (unit)",
},
["lb-mol/d"] = {
name1 = "pound-mole per day",
name2 = "pound-moles per day",
symbol = "lb‑mol/d",
utype = "molar rate",
scale = 0.0052499116898148141,
default = "mmol/s",
link = "Pound-mole",
},
["lb-mol/h"] = {
name1 = "pound-mole per hour",
name2 = "pound-moles per hour",
symbol = "lb‑mol/h",
utype = "molar rate",
scale = 0.12599788055555555,
default = "mol/s",
link = "Pound-mole",
},
["lb-mol/min"] = {
name1 = "pound-mole per minute",
name2 = "pound-moles per minute",
symbol = "lb‑mol/min",
utype = "molar rate",
scale = 7.5598728333333334,
default = "mol/s",
link = "Pound-mole",
},
["lb-mol/s"] = {
name1 = "pound-mole per second",
name2 = "pound-moles per second",
symbol = "lb‑mol/s",
utype = "molar rate",
scale = 453.59237,
default = "kmol/s",
link = "Pound-mole",
},
["lbmol/d"] = {
name1 = "pound-mole per day",
name2 = "pound-moles per day",
symbol = "lbmol/d",
utype = "molar rate",
scale = 0.0052499116898148141,
default = "mmol/s",
link = "Pound-mole",
},
["lbmol/h"] = {
name1 = "pound-mole per hour",
name2 = "pound-moles per hour",
symbol = "lbmol/h",
utype = "molar rate",
scale = 0.12599788055555555,
default = "mol/s",
link = "Pound-mole",
},
["lbmol/min"] = {
name1 = "pound-mole per minute",
name2 = "pound-moles per minute",
symbol = "lbmol/min",
utype = "molar rate",
scale = 7.5598728333333334,
default = "mol/s",
link = "Pound-mole",
},
["lbmol/s"] = {
name1 = "pound-mole per second",
name2 = "pound-moles per second",
symbol = "lbmol/s",
utype = "molar rate",
scale = 453.59237,
default = "kmol/s",
link = "Pound-mole",
},
["mmol/s"] = {
name1 = "millimole per second",
name2 = "millimoles per second",
symbol = "mmol/s",
utype = "molar rate",
scale = 0.001,
default = "lb-mol/d",
link = "Mole (unit)",
},
["mol/d"] = {
name1 = "mole per day",
name2 = "moles per day",
symbol = "mol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["mol/h"] = {
name1 = "mole per hour",
name2 = "moles per hour",
symbol = "mol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["mol/min"] = {
name1 = "mole per minute",
name2 = "moles per minute",
symbol = "mol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "mol/s",
link = "Mole (unit)",
},
["mol/s"] = {
name1 = "mole per second",
name2 = "moles per second",
symbol = "mol/s",
utype = "molar rate",
scale = 1,
default = "lb-mol/min",
link = "Mole (unit)",
},
["μmol/s"] = {
name1 = "micromole per second",
name2 = "micromoles per second",
symbol = "μmol/s",
utype = "molar rate",
scale = 0.000001,
default = "lb-mol/d",
link = "Mole (unit)",
},
["umol/s"] = {
target = "μmol/s",
},
["/acre"] = {
name1 = "per acre",
name2 = "per acre",
symbol = "/acre",
utype = "per unit area",
scale = 0.00024710538146716532,
default = "/ha",
link = "Acre",
},
["/ha"] = {
name1 = "per hectare",
name2 = "per hectare",
symbol = "/ha",
utype = "per unit area",
scale = 100e-6,
default = "/acre",
link = "Hectare",
},
["/sqcm"] = {
name1 = "per square centimetre",
name1_us = "per square centimeter",
name2 = "per square centimetre",
name2_us = "per square centimeter",
symbol = "/cm<sup>2</sup>",
utype = "per unit area",
scale = 1e4,
default = "/sqin",
link = "Square centimetre",
},
["/sqin"] = {
name1 = "per square inch",
name2 = "per square inch",
symbol = "/in<sup>2</sup>",
utype = "per unit area",
scale = 1550.0031000062002,
default = "/sqcm",
link = "Square inch",
},
["/sqkm"] = {
name1 = "per square kilometre",
name1_us = "per square kilometer",
name2 = "per square kilometre",
name2_us = "per square kilometer",
symbol = "/km<sup>2</sup>",
utype = "per unit area",
scale = 1e-6,
default = "/sqmi",
link = "Square kilometre",
},
["/sqmi"] = {
name1 = "per square mile",
name2 = "per square mile",
symbol = "/sq mi",
utype = "per unit area",
scale = 3.8610215854244582e-7,
default = "/sqkm",
link = "Square mile",
},
["PD/acre"] = {
name1 = "inhabitant per acre",
name2 = "inhabitants per acre",
symbol = "/acre",
utype = "per unit area",
scale = 0.00024710538146716532,
default = "PD/ha",
link = "Acre",
},
["PD/ha"] = {
name1 = "inhabitant per hectare",
name2 = "inhabitants per hectare",
symbol = "/ha",
utype = "per unit area",
scale = 100e-6,
default = "PD/acre",
link = "Hectare",
},
["PD/sqkm"] = {
name1 = "inhabitant per square kilometre",
name1_us = "inhabitant per square kilometer",
name2 = "inhabitants per square kilometre",
name2_us = "inhabitants per square kilometer",
symbol = "/km<sup>2</sup>",
utype = "per unit area",
scale = 1e-6,
default = "PD/sqmi",
link = "Square kilometre",
},
["PD/sqmi"] = {
name1 = "inhabitant per square mile",
name2 = "inhabitants per square mile",
symbol = "/sq mi",
utype = "per unit area",
scale = 3.8610215854244582e-7,
default = "PD/sqkm",
link = "Square mile",
},
["/cm2"] = {
target = "/sqcm",
},
["/in2"] = {
target = "/sqin",
},
["/km2"] = {
target = "/sqkm",
},
["pd/acre"] = {
target = "PD/acre",
},
["pd/ha"] = {
target = "PD/ha",
},
["PD/km2"] = {
target = "PD/sqkm",
},
["pd/km2"] = {
target = "PD/sqkm",
},
["PD/km²"] = {
target = "PD/sqkm",
},
["pd/sqkm"] = {
target = "PD/sqkm",
},
["pd/sqmi"] = {
target = "PD/sqmi",
},
["/l"] = {
name1 = "per litre",
name1_us = "per liter",
name2 = "per litre",
name2_us = "per liter",
symbol = "/l",
utype = "per unit volume",
scale = 1000,
default = "/usgal",
link = "Litre",
},
["/USgal"] = {
name1 = "per gallon",
name2 = "per gallon",
symbol = "/gal",
utype = "per unit volume",
scale = 264.172052,
default = "/l",
link = "US gallon",
customary= 2,
},
["/usgal"] = {
target = "/USgal",
},
["bhp"] = {
name1 = "brake horsepower",
name2 = "brake horsepower",
symbol = "bhp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Brake horsepower",
},
["Cal/d"] = {
name1 = "large calorie per day",
name2 = "large calories per day",
symbol = "Cal/d",
utype = "power",
scale = 0.048425925925925928,
default = "kJ/d",
link = "Calorie",
},
["Cal/h"] = {
name1 = "large calorie per hour",
name2 = "large calories per hour",
symbol = "Cal/h",
utype = "power",
scale = 1.1622222222222223,
default = "kJ/h",
link = "Calorie",
},
["cal/h"] = {
name1 = "calorie per hour",
name2 = "calories per hour",
symbol = "cal/h",
utype = "power",
scale = 0.0011622222222222223,
default = "W",
link = "Calorie",
},
["CV"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "CV",
utype = "power",
scale = 735.49875,
default = "kW",
},
["hk"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "hk",
utype = "power",
scale = 735.49875,
default = "kW",
},
["hp"] = {
name1 = "horsepower",
name2 = "horsepower",
symbol = "hp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
},
["hp-electric"] = {
name1 = "electric horsepower",
name2 = "electric horsepower",
symbol = "hp",
utype = "power",
scale = 746,
default = "kW",
link = "Horsepower#Electrical horsepower",
},
["hp-electrical"] = {
name1 = "electrical horsepower",
name2 = "electrical horsepower",
symbol = "hp",
utype = "power",
scale = 746,
default = "kW",
link = "Horsepower#Electrical horsepower",
},
["hp-metric"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "hp",
utype = "power",
scale = 735.49875,
default = "kW",
},
["ihp"] = {
name1 = "indicated horsepower",
name2 = "indicated horsepower",
symbol = "ihp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Indicated horsepower",
},
["kcal/h"] = {
name1 = "kilocalorie per hour",
name2 = "kilocalories per hour",
symbol = "kcal/h",
utype = "power",
scale = 1.1622222222222223,
default = "kW",
link = "Calorie",
},
["kJ/d"] = {
name1 = "kilojoule per day",
name2 = "kilojoules per day",
symbol = "kJ/d",
utype = "power",
scale = 0.011574074074074073,
default = "Cal/d",
link = "Kilojoule",
},
["kJ/h"] = {
name1 = "kilojoule per hour",
name2 = "kilojoules per hour",
symbol = "kJ/h",
utype = "power",
scale = 0.27777777777777779,
default = "W",
link = "Kilojoule",
},
["PS"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "PS",
utype = "power",
scale = 735.49875,
default = "kW",
},
["shp"] = {
name1 = "shaft horsepower",
name2 = "shaft horsepower",
symbol = "shp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Shaft horsepower",
},
["W"] = {
_name1 = "watt",
_symbol = "W",
utype = "power",
scale = 1,
prefixes = 1,
default = "hp",
link = "Watt",
},
["BTU/h"] = {
per = { "BTU", "h" },
utype = "power",
default = "W",
},
["Btu/h"] = {
per = { "Btu", "h" },
utype = "power",
default = "W",
},
["BHP"] = {
target = "bhp",
},
["btu/h"] = {
target = "BTU/h",
},
["HP"] = {
target = "hp",
},
["Hp"] = {
target = "hp",
},
["hp-mechanical"] = {
target = "hp",
},
["IHP"] = {
target = "ihp",
},
["SHP"] = {
target = "shp",
},
["whp"] = {
target = "hp",
},
["hp/lb"] = {
name1 = "horsepower per pound",
name2 = "horsepower per pound",
symbol = "hp/lb",
utype = "power per unit mass",
scale = 1643.986806,
default = "kW/kg",
link = "Power-to-weight ratio",
},
["hp/LT"] = {
name1 = "horsepower per long ton",
name2 = "horsepower per long ton",
symbol = "hp/LT",
utype = "power per unit mass",
scale = 0.73392268125000004,
default = "kW/t",
link = "Power-to-weight ratio",
},
["hp/ST"] = {
name1 = "horsepower per short ton",
name2 = "horsepower per short ton",
symbol = "hp/ST",
utype = "power per unit mass",
scale = 0.821993403,
default = "kW/t",
link = "Power-to-weight ratio",
},
["hp/t"] = {
name1 = "horsepower per tonne",
name2 = "horsepower per tonne",
symbol = "hp/t",
utype = "power per unit mass",
scale = 0.74569987158227022,
default = "kW/t",
link = "Power-to-weight ratio",
},
["kW/kg"] = {
name1 = "kilowatt per kilogram",
name2 = "kilowatts per kilogram",
symbol = "kW/kg",
utype = "power per unit mass",
scale = 1000,
default = "hp/lb",
link = "Power-to-weight ratio",
},
["kW/t"] = {
name1 = "kilowatt per tonne",
name2 = "kilowatts per tonne",
symbol = "kW/t",
utype = "power per unit mass",
scale = 1,
default = "PS/t",
link = "Power-to-weight ratio",
},
["PS/t"] = {
name1 = "metric horsepower per tonne",
name2 = "metric horsepower per tonne",
symbol = "PS/t",
utype = "power per unit mass",
scale = 0.73549875,
default = "kW/t",
link = "Power-to-weight ratio",
},
["shp/lb"] = {
name1 = "shaft horsepower per pound",
name2 = "shaft horsepower per pound",
symbol = "shp/lb",
utype = "power per unit mass",
scale = 1643.986806,
default = "kW/kg",
link = "Power-to-weight ratio",
},
["hp/tonne"] = {
target = "hp/t",
symbol = "hp/tonne",
default = "kW/tonne",
},
["kW/tonne"] = {
target = "kW/t",
symbol = "kW/tonne",
},
["-lb/in2"] = {
name1 = "pound per square inch",
name2 = "pounds per square inch",
symbol = "lb/in<sup>2</sup>",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa kgf/cm2",
},
["atm"] = {
name1 = "standard atmosphere",
symbol = "atm",
utype = "pressure",
scale = 101325,
default = "kPa",
link = "Atmosphere (unit)",
},
["Ba"] = {
name1 = "barye",
symbol = "Ba",
utype = "pressure",
scale = 0.1,
default = "Pa",
},
["bar"] = {
symbol = "bar",
utype = "pressure",
scale = 100000,
default = "kPa",
link = "Bar (unit)",
},
["dbar"] = {
name1 = "decibar",
symbol = "dbar",
utype = "pressure",
scale = 10000,
default = "kPa",
link = "Bar (unit)",
},
["inHg"] = {
name1 = "inch of mercury",
name2 = "inches of mercury",
symbol = "inHg",
utype = "pressure",
scale = 3386.388640341,
default = "kPa",
},
["kBa"] = {
name1 = "kilobarye",
symbol = "kBa",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Barye",
},
["kg-f/cm2"] = {
name1 = "kilogram-force per square centimetre",
name1_us = "kilogram-force per square centimeter",
name2 = "kilograms-force per square centimetre",
name2_us = "kilograms-force per square centimeter",
symbol = "kg<sub>f</sub>/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["kg/cm2"] = {
name1 = "kilogram per square centimetre",
name1_us = "kilogram per square centimeter",
name2 = "kilograms per square centimetre",
name2_us = "kilograms per square centimeter",
symbol = "kg/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["kgf/cm2"] = {
name1 = "kilogram-force per square centimetre",
name1_us = "kilogram-force per square centimeter",
name2 = "kilograms-force per square centimetre",
name2_us = "kilograms-force per square centimeter",
symbol = "kgf/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["ksi"] = {
name1 = "kilopound per square inch",
name2 = "kilopounds per square inch",
symbol = "ksi",
utype = "pressure",
scale = 6894757.2931683613,
default = "MPa",
link = "Pound per square inch",
},
["lbf/in2"] = {
name1 = "pound-force per square inch",
name2 = "pounds-force per square inch",
symbol = "lbf/in<sup>2</sup>",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa kgf/cm2",
},
["mb"] = {
name1 = "millibar",
symbol = "mb",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Bar (unit)",
},
["mbar"] = {
name1 = "millibar",
symbol = "mbar",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Bar (unit)",
},
["mmHg"] = {
name1 = "millimetre of mercury",
name1_us = "millimeter of mercury",
name2 = "millimetres of mercury",
name2_us = "millimeters of mercury",
symbol = "mmHg",
utype = "pressure",
scale = 133.322387415,
default = "kPa",
},
["Pa"] = {
_name1 = "pascal",
_symbol = "Pa",
utype = "pressure",
scale = 1,
prefixes = 1,
default = "psi",
link = "Pascal (unit)",
},
["psf"] = {
name1 = "pound per square foot",
name2 = "pounds per square foot",
symbol = "psf",
utype = "pressure",
scale = 47.880258980335839,
default = "kPa",
link = "Pound per square inch",
},
["psi"] = {
name1 = "pound per square inch",
name2 = "pounds per square inch",
symbol = "psi",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa",
},
["Torr"] = {
name1 = "torr",
symbol = "Torr",
utype = "pressure",
scale = 133.32236842105263,
default = "kPa",
},
["N/cm2"] = {
per = { "N", "cm2" },
utype = "pressure",
default = "psi",
},
["N/m2"] = {
per = { "N", "m2" },
utype = "pressure",
default = "psi",
},
["g/cm2"] = {
per = { "g", "cm2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["g/m2"] = {
per = { "g", "m2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["kg/ha"] = {
per = { "kg", "ha" },
utype = "pressure",
default = "lb/acre",
multiplier= 9.80665,
},
["kg/m2"] = {
per = { "kg", "m2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["lb/1000sqft"] = {
per = { "lb", "1000sqft" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["lb/acre"] = {
per = { "lb", "acre" },
utype = "pressure",
default = "kg/ha",
multiplier= 9.80665,
},
["lb/sqft"] = {
per = { "lb", "sqft" },
utype = "pressure",
default = "kg/m2",
multiplier= 9.80665,
},
["lb/sqyd"] = {
per = { "lb", "sqyd" },
utype = "pressure",
default = "kg/m2",
multiplier= 9.80665,
},
["LT/acre"] = {
per = { "LT", "acre" },
utype = "pressure",
default = "t/ha",
multiplier= 9.80665,
},
["MT/ha"] = {
per = { "MT", "ha" },
utype = "pressure",
default = "LT/acre ST/acre",
multiplier= 9.80665,
},
["oz/sqft"] = {
per = { "oz", "sqft" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["oz/sqyd"] = {
per = { "oz", "sqyd" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["ST/acre"] = {
per = { "ST", "acre" },
utype = "pressure",
default = "t/ha",
multiplier= 9.80665,
},
["t/ha"] = {
per = { "t", "ha" },
utype = "pressure",
default = "LT/acre ST/acre",
multiplier= 9.80665,
},
["tonne/acre"] = {
per = { "tonne", "acre" },
utype = "pressure",
default = "tonne/ha",
multiplier= 9.80665,
},
["tonne/ha"] = {
per = { "tonne", "ha" },
utype = "pressure",
default = "tonne/acre",
multiplier= 9.80665,
},
["kgfpsqcm"] = {
target = "kgf/cm2",
},
["kgpsqcm"] = {
target = "kg/cm2",
},
["kN/m2"] = {
target = "kPa",
},
["lb/in2"] = {
target = "lbf/in2",
},
["torr"] = {
target = "Torr",
},
["Bq"] = {
_name1 = "becquerel",
_symbol = "Bq",
utype = "radioactivity",
scale = 1,
prefixes = 1,
default = "pCi",
link = "Becquerel",
},
["Ci"] = {
_name1 = "curie",
_symbol = "Ci",
utype = "radioactivity",
scale = 3.7e10,
prefixes = 1,
default = "GBq",
link = "Curie (unit)",
},
["Rd"] = {
_name1 = "rutherford",
_symbol = "Rd",
utype = "radioactivity",
scale = 1e6,
prefixes = 1,
default = "MBq",
link = "Rutherford (unit)",
},
["cm/h"] = {
name1 = "centimetre per hour",
name1_us = "centimeter per hour",
name2 = "centimetres per hour",
name2_us = "centimeters per hour",
symbol = "cm/h",
utype = "speed",
scale = 2.7777777777777775e-6,
default = "in/h",
link = "Metre per second",
},
["cm/s"] = {
name1 = "centimetre per second",
name1_us = "centimeter per second",
name2 = "centimetres per second",
name2_us = "centimeters per second",
symbol = "cm/s",
utype = "speed",
scale = 0.01,
default = "in/s",
link = "Metre per second",
},
["cm/year"] = {
name1 = "centimetre per year",
name1_us = "centimeter per year",
name2 = "centimetres per year",
name2_us = "centimeters per year",
symbol = "cm/year",
utype = "speed",
scale = 3.168873850681143e-10,
default = "in/year",
link = "Orders of magnitude (speed)",
},
["foot/s"] = {
name1 = "foot per second",
name2 = "foot per second",
symbol = "ft/s",
utype = "speed",
scale = 0.3048,
default = "m/s",
},
["ft/min"] = {
name1 = "foot per minute",
name2 = "feet per minute",
symbol = "ft/min",
utype = "speed",
scale = 0.00508,
default = "m/min",
link = "Feet per second",
},
["ft/s"] = {
name1 = "foot per second",
name2 = "feet per second",
symbol = "ft/s",
utype = "speed",
scale = 0.3048,
default = "m/s",
link = "Feet per second",
},
["furlong per fortnight"] = {
name2 = "furlongs per fortnight",
symbol = "furlong per fortnight",
usename = 1,
utype = "speed",
scale = 0.00016630952380952381,
default = "km/h mph",
link = "FFF system",
},
["in/h"] = {
name1 = "inch per hour",
name2 = "inches per hour",
symbol = "in/h",
utype = "speed",
scale = 7.0555555555555559e-6,
default = "cm/h",
link = "Inch",
},
["in/s"] = {
name1 = "inch per second",
name2 = "inches per second",
symbol = "in/s",
utype = "speed",
scale = 0.0254,
default = "cm/s",
link = "Inch",
},
["in/year"] = {
name1 = "inch per year",
name2 = "inches per year",
symbol = "in/year",
utype = "speed",
scale = 8.0489395807301024e-10,
default = "cm/year",
link = "Orders of magnitude (speed)",
},
["isp"] = {
name1 = "second",
symbol = "s",
utype = "speed",
scale = 9.80665,
default = "km/s",
link = "Specific impulse",
},
["km/d"] = {
name1 = "kilometre per day",
name1_us = "kilometer per day",
name2 = "kilometres per day",
name2_us = "kilometers per day",
symbol = "km/d",
utype = "speed",
scale = 1.1574074074074074e-2,
default = "mi/d",
link = "Orders of magnitude (speed)",
},
["km/h"] = {
name1 = "kilometre per hour",
name1_us = "kilometer per hour",
name2 = "kilometres per hour",
name2_us = "kilometers per hour",
symbol = "km/h",
utype = "speed",
scale = 0.27777777777777779,
default = "mph",
link = "Kilometres per hour",
},
["km/s"] = {
name1 = "kilometre per second",
name1_us = "kilometer per second",
name2 = "kilometres per second",
name2_us = "kilometers per second",
symbol = "km/s",
utype = "speed",
scale = 1000,
default = "mi/s",
link = "Metre per second",
},
["kn"] = {
name1 = "knot",
symbol = "kn",
utype = "speed",
scale = 0.51444444444444448,
default = "km/h mph",
link = "Knot (unit)",
},
["kNs/kg"] = {
name2 = "kN‑s/kg",
symbol = "kN‑s/kg",
utype = "speed",
scale = 1000,
default = "isp",
link = "Specific impulse",
},
["m/min"] = {
name1 = "metre per minute",
name1_us = "meter per minute",
name2 = "metres per minute",
name2_us = "meters per minute",
symbol = "m/min",
utype = "speed",
scale = 0.016666666666666666,
default = "ft/min",
link = "Metre per second",
},
["m/s"] = {
name1 = "metre per second",
name1_us = "meter per second",
name2 = "metres per second",
name2_us = "meters per second",
symbol = "m/s",
utype = "speed",
scale = 1,
default = "ft/s",
},
["Mach"] = {
name2 = "Mach",
symbol = "Mach",
utype = "speed",
builtin = "mach",
scale = 0,
iscomplex= true,
default = "km/h mph",
link = "Mach number",
},
["mi/d"] = {
name1 = "mile per day",
name2 = "miles per day",
symbol = "mi/d",
utype = "speed",
scale = 1.8626666666666667e-2,
default = "km/d",
link = "Orders of magnitude (speed)",
},
["mi/s"] = {
name1 = "mile per second",
name2 = "miles per second",
symbol = "mi/s",
utype = "speed",
scale = 1609.344,
default = "km/s",
link = "Mile",
},
["mm/h"] = {
name1 = "millimetre per hour",
name1_us = "millimeter per hour",
name2 = "millimetres per hour",
name2_us = "millimeters per hour",
symbol = "mm/h",
utype = "speed",
scale = 2.7777777777777781e-7,
default = "in/h",
link = "Metre per second",
},
["mph"] = {
name1 = "mile per hour",
name2 = "miles per hour",
symbol = "mph",
utype = "speed",
scale = 0.44704,
default = "km/h",
link = "Miles per hour",
},
["Ns/kg"] = {
name2 = "N‑s/kg",
symbol = "N‑s/kg",
utype = "speed",
scale = 1,
default = "isp",
link = "Specific impulse",
},
["si tsfc"] = {
name2 = "g/(kN⋅s)",
symbol = "g/(kN⋅s)",
utype = "speed",
scale = 9.9999628621379242e-7,
invert = -1,
iscomplex= true,
default = "tsfc",
link = "Thrust specific fuel consumption",
},
["tsfc"] = {
name2 = "lb/(lbf⋅h)",
symbol = "lb/(lbf⋅h)",
utype = "speed",
scale = 2.832545036049801e-5,
invert = -1,
iscomplex= true,
default = "si tsfc",
link = "Thrust specific fuel consumption",
},
["cm/y"] = {
target = "cm/year",
},
["cm/yr"] = {
target = "cm/year",
},
["in/y"] = {
target = "in/year",
},
["in/yr"] = {
target = "in/year",
},
["knot"] = {
target = "kn",
},
["knots"] = {
target = "kn",
},
["kph"] = {
target = "km/h",
},
["mi/h"] = {
target = "mph",
},
["mm/s"] = {
per = { "mm", "s" },
utype = "speed",
default = "in/s",
link = "Metre per second",
},
["C"] = {
name1 = "degree Celsius",
name2 = "degrees Celsius",
symbol = "°C",
usesymbol= 1,
utype = "temperature",
scale = 1,
offset = -273.15,
iscomplex= true,
istemperature= true,
default = "F",
link = "Celsius",
},
["F"] = {
name1 = "degree Fahrenheit",
name2 = "degrees Fahrenheit",
symbol = "°F",
usesymbol= 1,
utype = "temperature",
scale = 0.55555555555555558,
offset = 32-273.15*(9/5),
iscomplex= true,
istemperature= true,
default = "C",
link = "Fahrenheit",
},
["K"] = {
_name1 = "kelvin",
_symbol = "K",
usesymbol= 1,
utype = "temperature",
scale = 1,
offset = 0,
iscomplex= true,
istemperature= true,
prefixes = 1,
default = "C F",
link = "Kelvin",
},
["keVT"] = {
name1 = "kiloelectronvolt",
symbol = "keV",
utype = "temperature",
scale = 11.604505e6,
offset = 0,
iscomplex= true,
default = "MK",
link = "Electronvolt",
},
["R"] = {
name1 = "degree Rankine",
name2 = "degrees Rankine",
symbol = "°R",
usesymbol= 1,
utype = "temperature",
scale = 0.55555555555555558,
offset = 0,
iscomplex= true,
istemperature= true,
default = "K F C",
link = "Rankine scale",
},
["Celsius"] = {
target = "C",
},
["°C"] = {
target = "C",
},
["°F"] = {
target = "F",
},
["°R"] = {
target = "R",
},
["C-change"] = {
name1 = "degree Celsius change",
name2 = "degrees Celsius change",
symbol = "°C",
usesymbol= 1,
utype = "temperature change",
scale = 1,
default = "F-change",
link = "Celsius",
},
["F-change"] = {
name1 = "degree Fahrenheit change",
name2 = "degrees Fahrenheit change",
symbol = "°F",
usesymbol= 1,
utype = "temperature change",
scale = 0.55555555555555558,
default = "C-change",
link = "Fahrenheit",
},
["K-change"] = {
name1 = "kelvin change",
name2 = "kelvins change",
symbol = "K",
usesymbol= 1,
utype = "temperature change",
scale = 1,
default = "F-change",
link = "Kelvin",
},
["°C-change"] = {
target = "C-change",
},
["°F-change"] = {
target = "F-change",
},
["century"] = {
name1 = "century",
name2 = "centuries",
symbol = "ha",
utype = "time",
scale = 3155760000,
default = "Gs",
},
["d"] = {
name1 = "day",
symbol = "d",
utype = "time",
scale = 86400,
default = "ks",
},
["decade"] = {
name1 = "decade",
symbol = "daa",
utype = "time",
scale = 315576000,
default = "Ms",
},
["dog year"] = {
name1 = "dog year",
symbol = "dog yr",
utype = "time",
scale = 220903200,
default = "years",
link = "List of unusual units of measurement#Dog year",
},
["fortnight"] = {
symbol = "fortnight",
usename = 1,
utype = "time",
scale = 1209600,
default = "week",
},
["h"] = {
name1 = "hour",
symbol = "h",
utype = "time",
scale = 3600,
default = "ks",
},
["long billion year"] = {
name1 = "billion years",
name2 = "billion years",
symbol = "Ta",
utype = "time",
scale = 31557600000000000000,
default = "Es",
link = "Annum",
},
["millennium"] = {
name1 = "millennium",
name2 = "millennia",
symbol = "ka",
utype = "time",
scale = 31557600000,
default = "Gs",
},
["milliard year"] = {
name1 = "milliard years",
name2 = "milliard years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["million year"] = {
name1 = "million years",
name2 = "million years",
symbol = "Ma",
utype = "time",
scale = 31557600000000,
default = "Ts",
link = "Annum",
},
["min"] = {
name1 = "minute",
symbol = "min",
utype = "time",
scale = 60,
default = "s",
},
["month"] = {
symbol = "month",
usename = 1,
utype = "time",
scale = 2629800,
default = "Ms",
},
["months"] = {
name1 = "month",
symbol = "mo",
utype = "time",
scale = 2629800,
default = "year",
},
["s"] = {
_name1 = "second",
_symbol = "s",
utype = "time",
scale = 1,
prefixes = 1,
default = "min",
link = "Second",
},
["short billion year"] = {
name1 = "billion years",
name2 = "billion years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["short trillion year"] = {
name1 = "trillion years",
name2 = "trillion years",
symbol = "Ta",
utype = "time",
scale = 31557600000000000000,
default = "Es",
link = "Annum",
},
["thousand million year"] = {
name1 = "thousand million years",
name2 = "thousand million years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["wk"] = {
symbol = "week",
usename = 1,
utype = "time",
scale = 604800,
default = "Ms",
},
["year"] = {
name1 = "year",
symbol = "a",
utype = "time",
scale = 31557600,
default = "Ms",
link = "Annum",
},
["years"] = {
name1 = "year",
symbol = "yr",
utype = "time",
scale = 31557600,
default = "Ms",
link = "Annum",
},
["byr"] = {
target = "short billion year",
},
["day"] = {
target = "d",
},
["days"] = {
target = "d",
},
["dog yr"] = {
target = "dog year",
},
["Gyr"] = {
target = "thousand million year",
},
["hour"] = {
target = "h",
},
["hours"] = {
target = "h",
},
["kMyr"] = {
target = "thousand million year",
},
["kmyr"] = {
target = "thousand million year",
},
["kyr"] = {
target = "millennium",
},
["long byr"] = {
target = "long billion year",
},
["minute"] = {
target = "min",
},
["minutes"] = {
target = "min",
},
["mth"] = {
target = "month",
},
["Myr"] = {
target = "million year",
},
["myr"] = {
target = "million year",
},
["second"] = {
target = "s",
},
["seconds"] = {
target = "s",
},
["tmyr"] = {
target = "thousand million year",
},
["tryr"] = {
target = "short trillion year",
},
["tyr"] = {
target = "millennium",
},
["week"] = {
target = "wk",
},
["weeks"] = {
target = "wk",
},
["yr"] = {
target = "year",
},
["kg.m"] = {
name1 = "kilogram metre",
name1_us = "kilogram meter",
symbol = "kg⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbft",
link = "Kilogram metre (torque)",
},
["kgf.m"] = {
name1 = "kilogram force-metre",
name1_us = "kilogram force-meter",
symbol = "kgf⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["kgm"] = {
name1 = "kilogram metre",
name1_us = "kilogram meter",
symbol = "kg⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["kpm"] = {
name1 = "kilopond metre",
name1_us = "kilopond meter",
symbol = "kp⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbft",
link = "Kilogram metre (torque)",
},
["lb-fft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "ft⋅lb<sub>f</sub>",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lb.ft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "lb⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lb.in"] = {
name1 = "pound force-inch",
symbol = "lb⋅in",
utype = "torque",
scale = 0.1129848290276167,
default = "mN.m",
link = "Pound-foot (torque)",
},
["lbfft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "lbf⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lbft"] = {
name1 = "pound-foot",
name2 = "pound-feet",
symbol = "lb⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["m.kg-f"] = {
name1 = "metre kilogram-force",
name1_us = "meter kilogram-force",
name2 = "metre kilograms-force",
name2_us = "meter kilograms-force",
symbol = "m⋅kg<sub>f</sub>",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["m.kgf"] = {
name1 = "metre kilogram-force",
name1_us = "meter kilogram-force",
name2 = "metre kilograms-force",
name2_us = "meter kilograms-force",
symbol = "m⋅kgf",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["mN.m"] = {
name1 = "millinewton-metre",
name1_us = "millinewton-meter",
symbol = "mN⋅m",
utype = "torque",
scale = 0.001,
default = "lb.in",
link = "Newton-metre",
},
["Nm"] = {
_name1 = "newton-metre",
_name1_us= "newton-meter",
_symbol = "N⋅m",
utype = "torque",
alttype = "energy",
scale = 1,
prefixes = 1,
default = "lbfft",
link = "Newton-metre",
},
["kN/m"] = {
per = { "kN", "-m-stiff" },
utype = "torque",
default = "lbf/in",
},
["lbf/in"] = {
per = { "lbf", "-in-stiff" },
utype = "torque",
default = "kN/m",
},
["lb-f.ft"] = {
target = "lb-fft",
},
["lbf.ft"] = {
target = "lbfft",
},
["lbf·ft"] = {
target = "lbfft",
},
["lb·ft"] = {
target = "lb.ft",
},
["mkg-f"] = {
target = "m.kg-f",
},
["mkgf"] = {
target = "m.kgf",
},
["N.m"] = {
target = "Nm",
},
["N·m"] = {
target = "Nm",
},
["ton-mile"] = {
symbol = "ton-mile",
usename = 1,
utype = "transportation",
scale = 1.4599723182105602,
default = "tkm",
},
["tkm"] = {
name1 = "tonne-kilometre",
name1_us = "tonne-kilometer",
symbol = "tkm",
utype = "transportation",
scale = 1,
default = "ton-mile",
},
["-12USoz(mL)serve"] = {
name1_us = "12 U.S. fl oz (355 mL) serving",
symbol = "12 US fl oz (355 mL) serving",
sym_us = "12 U.S. fl oz (355 mL) serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "mL",
link = "Beverage can#Standard sizes",
},
["-12USoz(ml)serve"] = {
name1_us = "12 U.S. fl oz (355 ml) serving",
symbol = "12 US fl oz (355 ml) serving",
sym_us = "12 U.S. fl oz (355 ml) serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "ml",
link = "Beverage can#Standard sizes",
},
["-12USozserve"] = {
name1_us = "12 U.S. fl oz serving",
symbol = "12 US fl oz serving",
sym_us = "12 U.S. fl oz serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "mL",
link = "Beverage can#Standard sizes",
},
["acre-foot"] = {
name1 = "acre-foot",
name2 = "acre-foot",
symbol = "acre⋅ft",
utype = "volume",
scale = 1233.48183754752,
default = "m3",
},
["acre-ft"] = {
name1 = "acre-foot",
name2 = "acre-feet",
symbol = "acre⋅ft",
utype = "volume",
scale = 1233.48183754752,
default = "m3",
},
["AUtbsp"] = {
name1 = "Australian tablespoon",
symbol = "AU tbsp",
utype = "volume",
scale = 0.000020,
default = "ml",
},
["Bcuft"] = {
name1 = "billion cubic foot",
name2 = "billion cubic feet",
symbol = "billion cu ft",
utype = "volume",
scale = 28316846.592,
default = "Gl",
link = "Cubic foot",
},
["bdft"] = {
name1 = "board foot",
name2 = "board feet",
symbol = "bd ft",
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["board feet"] = {
name2 = "board feet",
symbol = "board foot",
usename = 1,
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["board foot"] = {
name2 = "board foot",
symbol = "board foot",
usename = 1,
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["cc"] = {
name1 = "cubic centimetre",
name1_us = "cubic centimeter",
symbol = "cc",
utype = "volume",
scale = 0.000001,
default = "cuin",
},
["CID"] = {
name1 = "cubic inch",
name2 = "cubic inches",
symbol = "cu in",
utype = "volume",
scale = 0.000016387064,
default = "cc",
link = "Cubic inch#Engine displacement",
},
["cord"] = {
symbol = "cord",
utype = "volume",
scale = 3.624556363776,
default = "m3",
link = "Cord (unit)",
},
["cufoot"] = {
name1 = "cubic foot",
name2 = "cubic foot",
symbol = "cu ft",
utype = "volume",
scale = 0.028316846592,
default = "m3",
},
["cuft"] = {
name1 = "cubic foot",
name2 = "cubic feet",
symbol = "cu ft",
utype = "volume",
scale = 0.028316846592,
default = "m3",
},
["cuin"] = {
name1 = "cubic inch",
name2 = "cubic inches",
symbol = "cu in",
utype = "volume",
scale = 0.000016387064,
default = "cm3",
},
["cumi"] = {
name1 = "cubic mile",
symbol = "cu mi",
utype = "volume",
scale = 4168181825.440579584,
default = "km3",
},
["cuyd"] = {
name1 = "cubic yard",
symbol = "cu yd",
utype = "volume",
scale = 0.764554857984,
default = "m3",
},
["firkin"] = {
symbol = "firkin",
usename = 1,
utype = "volume",
scale = 0.04091481,
default = "l impgal USgal",
link = "Firkin (unit)",
},
["foot3"] = {
target = "cufoot",
},
["Goilbbl"] = {
name1 = "billion barrels",
name2 = "billion barrels",
symbol = "Gbbl",
utype = "volume",
scale = 158987294.928,
default = "v * 1.58987294928 < 10 ! e6 ! e9 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["gr water"] = {
name1 = "grains water",
name2 = "grains water",
symbol = "gr H<sub>2</sub>O",
utype = "volume",
scale = 0.00000006479891,
default = "cm3",
link = "Grain (unit)",
},
["grt"] = {
name1 = "gross register ton",
symbol = "grt",
utype = "volume",
scale = 2.8316846592,
default = "m3",
link = "Gross register tonnage",
},
["impbbl"] = {
name1 = "imperial barrel",
symbol = "imp bbl",
utype = "volume",
scale = 0.16365924,
default = "l impgal USgal",
link = "Barrel (unit)",
},
["impbsh"] = {
name1 = "imperial bushel",
symbol = "imp bsh",
utype = "volume",
scale = 0.03636872,
default = "l impgal USdrygal",
},
["impbu"] = {
name1 = "imperial bushel",
symbol = "imp bu",
utype = "volume",
scale = 0.03636872,
default = "m3",
},
["impgal"] = {
name1 = "imperial gallon",
symbol = "imp gal",
utype = "volume",
scale = 0.00454609,
default = "l USgal",
},
["impgi"] = {
name1 = "gill",
symbol = "gi",
utype = "volume",
scale = 0.0001420653125,
default = "ml USoz",
link = "Gill (unit)",
},
["impkenning"] = {
name1 = "imperial kenning",
symbol = "kenning",
utype = "volume",
scale = 0.01818436,
default = "l USdrygal",
link = "Kenning (unit)",
},
["impoz"] = {
name1 = "imperial fluid ounce",
symbol = "imp fl oz",
utype = "volume",
scale = 0.0000284130625,
default = "ml USoz",
},
["imppk"] = {
name1 = "imperial peck",
symbol = "pk",
utype = "volume",
scale = 0.00909218,
default = "l USdrygal",
link = "Peck",
},
["imppt"] = {
name1 = "imperial pint",
symbol = "imp pt",
utype = "volume",
scale = 0.00056826125,
default = "l",
},
["impqt"] = {
name1 = "imperial quart",
symbol = "imp qt",
utype = "volume",
scale = 0.0011365225,
default = "ml USoz",
customary= 3,
},
["kilderkin"] = {
symbol = "kilderkin",
usename = 1,
utype = "volume",
scale = 0.08182962,
default = "l impgal USgal",
},
["koilbbl"] = {
name1 = "thousand barrels",
name2 = "thousand barrels",
symbol = "kbbl",
utype = "volume",
scale = 158.987294928,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["L"] = {
_name1 = "litre",
_name1_us= "liter",
_symbol = "L",
utype = "volume",
scale = 0.001,
prefixes = 1,
default = "impgal USgal",
link = "Litre",
},
["l"] = {
_name1 = "litre",
_name1_us= "liter",
_symbol = "l",
utype = "volume",
scale = 0.001,
prefixes = 1,
default = "impgal USgal",
link = "Litre",
},
["m3"] = {
_name1 = "cubic metre",
_name1_us= "cubic meter",
_symbol = "m<sup>3</sup>",
prefix_position= 7,
utype = "volume",
scale = 1,
prefixes = 3,
default = "cuft",
link = "Cubic metre",
},
["Mbbl"] = {
name1 = "thousand barrels",
name2 = "thousand barrels",
symbol = "Mbbl",
utype = "volume",
scale = 158.987294928,
default = "v * 1.58987294928 < 10 ! e3 ! ! m3",
link = "Barrel (unit)#Oil barrel",
},
["MMoilbbl"] = {
name1 = "million barrels",
name2 = "million barrels",
symbol = "MMbbl",
utype = "volume",
scale = 158987.294928,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["Moilbbl"] = {
name1 = "million barrels",
name2 = "million barrels",
symbol = "Mbbl",
utype = "volume",
scale = 158987.294928,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["MTON"] = {
name1 = "measurement ton",
symbol = "MTON",
utype = "volume",
scale = 1.13267386368,
default = "m3",
},
["MUSgal"] = {
name1 = "million US gallons",
name1_us = "million U.S. gallons",
name2 = "million US gallons",
name2_us = "million U.S. gallons",
symbol = "million US gal",
sym_us = "million U.S. gal",
utype = "volume",
scale = 3785.411784,
default = "Ml",
link = "US gallon",
},
["oilbbl"] = {
name1 = "barrel",
symbol = "bbl",
utype = "volume",
scale = 0.158987294928,
default = "m3",
link = "Barrel (unit)#Oil barrel",
},
["stere"] = {
symbol = "stere",
usename = 1,
utype = "volume",
scale = 1,
default = "cuft",
},
["Toilbbl"] = {
name1 = "trillion barrels",
name2 = "trillion barrels",
symbol = "Tbbl",
utype = "volume",
scale = 158987294928,
default = "v * 1.58987294928 < 10 ! e9 ! e12 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["USbbl"] = {
name1 = "US barrel",
name1_us = "U.S. barrel",
symbol = "US bbl",
sym_us = "U.S. bbl",
utype = "volume",
scale = 0.119240471196,
default = "l USgal impgal",
link = "Barrel (unit)",
},
["USbeerbbl"] = {
name1 = "US beer barrel",
name1_us = "U.S. beer barrel",
symbol = "US bbl",
sym_us = "U.S. bbl",
utype = "volume",
scale = 0.117347765304,
default = "l USgal impgal",
link = "Barrel (unit)",
},
["USbsh"] = {
name1 = "US bushel",
name1_us = "U.S. bushel",
symbol = "US bsh",
sym_us = "U.S. bsh",
utype = "volume",
scale = 0.03523907016688,
default = "l USdrygal impgal",
link = "Bushel",
},
["USbu"] = {
name1 = "US bushel",
name1_us = "U.S. bushel",
symbol = "US bu",
sym_us = "U.S. bu",
utype = "volume",
scale = 0.03523907016688,
default = "l USdrygal impgal",
link = "Bushel",
},
["USdrybbl"] = {
name1 = "US dry barrel",
name1_us = "U.S. dry barrel",
symbol = "US dry bbl",
sym_us = "U.S. dry bbl",
utype = "volume",
scale = 0.11562819898508,
default = "m3",
link = "Barrel (unit)",
},
["USdrygal"] = {
name1 = "US dry gallon",
name1_us = "U.S. dry gallon",
symbol = "US dry gal",
sym_us = "U.S. dry gal",
utype = "volume",
scale = 0.00440488377086,
default = "l",
link = "Gallon",
},
["USdrypt"] = {
name1 = "US dry pint",
name1_us = "U.S. dry pint",
symbol = "US dry pt",
sym_us = "U.S. dry pt",
utype = "volume",
scale = 0.0005506104713575,
default = "ml",
link = "Pint",
},
["USdryqt"] = {
name1 = "US dry quart",
name1_us = "U.S. dry quart",
symbol = "US dry qt",
sym_us = "U.S. dry qt",
utype = "volume",
scale = 0.001101220942715,
default = "ml",
link = "Quart",
},
["USflgal"] = {
name1 = "US gallon",
name1_us = "U.S. gallon",
symbol = "US fl gal",
sym_us = "U.S. fl gal",
utype = "volume",
scale = 0.003785411784,
default = "l impgal",
link = "Gallon",
},
["USgal"] = {
name1 = "US gallon",
name1_us = "U.S. gallon",
symbol = "US gal",
sym_us = "U.S. gal",
utype = "volume",
scale = 0.003785411784,
default = "l impgal",
},
["USgi"] = {
name1 = "gill",
symbol = "gi",
utype = "volume",
scale = 0.0001182941183,
default = "ml impoz",
link = "Gill (unit)",
},
["USkenning"] = {
name1 = "US kenning",
name1_us = "U.S. kenning",
symbol = "US kenning",
sym_us = "U.S. kenning",
utype = "volume",
scale = 0.01761953508344,
default = "l impgal",
link = "Kenning (unit)",
},
["USmin"] = {
name1 = "US minim",
name1_us = "U.S. minim",
symbol = "US min",
sym_us = "U.S. min",
utype = "volume",
scale = 0.000000061611519921875,
default = "ml",
link = "Minim (unit)",
},
["USoz"] = {
name1 = "US fluid ounce",
name1_us = "U.S. fluid ounce",
symbol = "US fl oz",
sym_us = "U.S. fl oz",
utype = "volume",
scale = 0.0000295735295625,
default = "ml",
},
["USpk"] = {
name1 = "US peck",
name1_us = "U.S. peck",
symbol = "US pk",
sym_us = "U.S. pk",
utype = "volume",
scale = 0.00880976754172,
default = "l impgal",
link = "Peck",
},
["USpt"] = {
name1 = "US pint",
name1_us = "U.S. pint",
symbol = "US pt",
sym_us = "U.S. pt",
utype = "volume",
scale = 0.000473176473,
default = "l imppt",
link = "Pint",
},
["USqt"] = {
name1 = "US quart",
name1_us = "U.S. quart",
symbol = "US qt",
sym_us = "U.S. qt",
utype = "volume",
scale = 0.000946352946,
default = "ml",
link = "Quart",
customary= 1,
},
["USquart"] = {
name1 = "US quart",
name1_us = "U.S. quart",
symbol = "US qt",
sym_us = "U.S. qt",
utype = "volume",
scale = 0.000946352946,
default = "ml impoz",
link = "Quart",
},
["UStbsp"] = {
name1 = "US tablespoon",
name1_us = "U.S. tablespoon",
symbol = "US tbsp",
sym_us = "U.S. tbsp",
utype = "volume",
scale = 1.4786764781250001e-5,
default = "ml",
},
["winecase"] = {
symbol = "case",
usename = 1,
utype = "volume",
scale = 0.009,
default = "l",
link = "Case (goods)",
},
["*U.S.drygal"] = {
target = "USdrygal",
sp_us = true,
customary= 2,
},
["*U.S.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
customary= 2,
},
["+USdrygal"] = {
target = "USdrygal",
customary= 1,
},
["+usfloz"] = {
target = "USoz",
link = "Fluid ounce",
customary= 1,
},
["+USgal"] = {
target = "USgal",
customary= 1,
},
["+USoz"] = {
target = "USoz",
customary= 1,
},
["@impgal"] = {
target = "impgal",
link = "Gallon",
customary= 3,
},
["acre feet"] = {
target = "acre-ft",
},
["acre foot"] = {
target = "acre-foot",
},
["acre ft"] = {
target = "acre-ft",
},
["acre-feet"] = {
target = "acre-ft",
},
["acre.foot"] = {
target = "acre-foot",
},
["acre.ft"] = {
target = "acre-ft",
},
["acre·ft"] = {
target = "acre-ft",
},
["bushels"] = {
target = "USbsh",
},
["cid"] = {
target = "CID",
},
["ft3"] = {
target = "cuft",
},
["gal"] = {
target = "USgal",
},
["gallon"] = {
shouldbe = "Use %{USgal%} for US gallons or %{impgal%} for imperial gallons (not %{gallon%})",
},
["gallons"] = {
shouldbe = "Use %{USgal%} for US gallons or %{impgal%} for imperial gallons (not %{gallons%})",
},
["Gcuft"] = {
target = "e9cuft",
},
["impfloz"] = {
target = "impoz",
},
["Impgal"] = {
target = "impgal",
},
["in3"] = {
target = "cuin",
symbol = "in<sup>3</sup>",
},
["kcuft"] = {
target = "e3cuft",
},
["kcum"] = {
target = "e3m3",
},
["km³"] = {
target = "km3",
},
["liter"] = {
target = "L",
sp_us = true,
},
["liters"] = {
target = "L",
sp_us = true,
},
["litre"] = {
target = "L",
},
["litres"] = {
target = "L",
},
["Mcuft"] = {
target = "e6cuft",
},
["Mcum"] = {
target = "e6m3",
},
["Mft3"] = {
target = "e6cuft",
},
["mi3"] = {
target = "cumi",
},
["m³"] = {
target = "m3",
},
["Pcuft"] = {
target = "e15cuft",
},
["pt"] = {
shouldbe = "Use %{USpt%} for US pints or %{imppt%} for imperial pints (not %{pt%})",
},
["qt"] = {
shouldbe = "Use %{USqt%} for US quarts or %{impqt%} for imperial quarts (not %{qt%})",
},
["Tcuft"] = {
target = "e12cuft",
},
["Tft3"] = {
target = "e12cuft",
},
["U.S.bbl"] = {
target = "USbbl",
sp_us = true,
default = "l U.S.gal impgal",
},
["U.S.beerbbl"] = {
target = "USbeerbbl",
sp_us = true,
default = "l U.S.gal impgal",
},
["U.S.bsh"] = {
target = "USbsh",
sp_us = true,
default = "l U.S.drygal impgal",
},
["U.S.bu"] = {
target = "USbu",
sp_us = true,
default = "l U.S.drygal impgal",
},
["U.S.drybbl"] = {
target = "USdrybbl",
sp_us = true,
},
["U.S.drygal"] = {
target = "USdrygal",
sp_us = true,
},
["U.S.drypt"] = {
target = "USdrypt",
sp_us = true,
},
["U.S.dryqt"] = {
target = "USdryqt",
sp_us = true,
},
["U.S.flgal"] = {
target = "USflgal",
sp_us = true,
},
["U.S.floz"] = {
target = "USoz",
sp_us = true,
},
["U.S.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
link = "U.S. gallon",
},
["u.s.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
link = "U.S. gallon",
},
["U.S.gi"] = {
target = "USgi",
sp_us = true,
},
["U.S.kenning"] = {
target = "USkenning",
sp_us = true,
},
["U.S.oz"] = {
target = "USoz",
sp_us = true,
},
["U.S.pk"] = {
target = "USpk",
sp_us = true,
},
["U.S.pt"] = {
target = "USpt",
sp_us = true,
},
["U.S.qt"] = {
target = "USqt",
sp_us = true,
default = "L impqt",
customary= 2,
},
["usbbl"] = {
target = "USbbl",
},
["usbeerbbl"] = {
target = "USbeerbbl",
},
["usbsh"] = {
target = "USbsh",
},
["usbu"] = {
target = "USbu",
},
["usdrybbl"] = {
target = "USdrybbl",
},
["usdrygal"] = {
target = "USdrygal",
},
["usdrypt"] = {
target = "USdrypt",
},
["usdryqt"] = {
target = "USdryqt",
},
["USfloz"] = {
target = "USoz",
},
["usfloz"] = {
target = "USoz",
},
["USGAL"] = {
target = "USgal",
},
["usgal"] = {
target = "USgal",
},
["usgi"] = {
target = "USgi",
},
["uskenning"] = {
target = "USkenning",
},
["usoz"] = {
target = "USoz",
},
["uspk"] = {
target = "USpk",
},
["uspt"] = {
target = "USpt",
},
["usqt"] = {
target = "USqt",
},
["yd3"] = {
target = "cuyd",
},
["cuft/sqmi"] = {
per = { "cuft", "sqmi" },
utype = "volume per unit area",
default = "m3/km2",
},
["m3/ha"] = {
name1 = "cubic metre per hectare",
name1_us = "cubic meter per hectare",
name2 = "cubic metres per hectare",
name2_us = "cubic meters per hectare",
symbol = "m<sup>3</sup>/ha",
utype = "volume per unit area",
scale = 0.0001,
default = "USbu/acre",
link = "Hectare",
},
["m3/km2"] = {
per = { "m3", "km2" },
utype = "volume per unit area",
default = "cuft/sqmi",
},
["U.S.gal/acre"] = {
per = { "U.S.gal", "acre" },
utype = "volume per unit area",
default = "m3/km2",
},
["USbu/acre"] = {
name2 = "US bushels per acre",
symbol = "US bushel per acre",
usename = 1,
utype = "volume per unit area",
scale = 8.7077638761350888e-6,
default = "m3/ha",
link = "Bushel",
},
["USgal/acre"] = {
per = { "USgal", "acre" },
utype = "volume per unit area",
default = "m3/km2",
},
["cuyd/mi"] = {
per = { "cuyd", "mi" },
utype = "volume per unit length",
default = "m3/km",
},
["m3/km"] = {
per = { "m3", "km" },
utype = "volume per unit length",
default = "cuyd/mi",
},
["mich"] = {
combination= { "ch", "mi" },
multiple = { 80 },
utype = "length",
},
["michlk"] = {
combination= { "chlk", "mi" },
multiple = { 80 },
utype = "length",
},
["michainlk"] = {
combination= { "chainlk", "mi" },
multiple = { 80 },
utype = "length",
},
["miyd"] = {
combination= { "yd", "mi" },
multiple = { 1760 },
utype = "length",
},
["miydftin"] = {
combination= { "in", "ft", "yd", "mi" },
multiple = { 12, 3, 1760 },
utype = "length",
},
["mift"] = {
combination= { "ft", "mi" },
multiple = { 5280 },
utype = "length",
},
["ydftin"] = {
combination= { "in", "ft", "yd" },
multiple = { 12, 3 },
utype = "length",
},
["ydft"] = {
combination= { "ft", "yd" },
multiple = { 3 },
utype = "length",
},
["ftin"] = {
combination= { "in", "ft" },
multiple = { 12 },
utype = "length",
},
["footin"] = {
combination= { "in", "foot" },
multiple = { 12 },
utype = "length",
},
["handin"] = {
combination= { "in", "hand" },
multiple = { 4 },
utype = "length",
},
["lboz"] = {
combination= { "oz", "lb" },
multiple = { 16 },
utype = "mass",
},
["stlb"] = {
combination= { "lb", "st" },
multiple = { 14 },
utype = "mass",
},
["stlboz"] = {
combination= { "oz", "lb", "st" },
multiple = { 16, 14 },
utype = "mass",
},
["st and lb"] = {
combination= { "lb", "st" },
multiple = { 14 },
utype = "mass",
},
["GN LTf"] = {
combination= { "GN", "-LTf" },
utype = "force",
},
["GN LTf STf"] = {
combination= { "GN", "-LTf", "-STf" },
utype = "force",
},
["GN STf"] = {
combination= { "GN", "-STf" },
utype = "force",
},
["GN STf LTf"] = {
combination= { "GN", "-STf", "-LTf" },
utype = "force",
},
["kN LTf"] = {
combination= { "kN", "-LTf" },
utype = "force",
},
["kN LTf STf"] = {
combination= { "kN", "-LTf", "-STf" },
utype = "force",
},
["kN STf"] = {
combination= { "kN", "-STf" },
utype = "force",
},
["kN STf LTf"] = {
combination= { "kN", "-STf", "-LTf" },
utype = "force",
},
["LTf STf"] = {
combination= { "-LTf", "-STf" },
utype = "force",
},
["MN LTf"] = {
combination= { "MN", "-LTf" },
utype = "force",
},
["MN LTf STf"] = {
combination= { "MN", "-LTf", "-STf" },
utype = "force",
},
["MN STf"] = {
combination= { "MN", "-STf" },
utype = "force",
},
["MN STf LTf"] = {
combination= { "MN", "-STf", "-LTf" },
utype = "force",
},
["STf LTf"] = {
combination= { "-STf", "-LTf" },
utype = "force",
},
["L/100 km mpgimp"] = {
combination= { "L/100 km", "mpgimp" },
utype = "fuel efficiency",
},
["l/100 km mpgimp"] = {
combination= { "l/100 km", "mpgimp" },
utype = "fuel efficiency",
},
["L/100 km mpgUS"] = {
combination= { "L/100 km", "mpgus" },
utype = "fuel efficiency",
},
["L/100 km mpgus"] = {
combination= { "L/100 km", "mpgus" },
utype = "fuel efficiency",
},
["l/100 km mpgus"] = {
combination= { "l/100 km", "mpgus" },
utype = "fuel efficiency",
},
["mpgimp L/100 km"] = {
combination= { "mpgimp", "L/100 km" },
utype = "fuel efficiency",
},
["LT ST t"] = {
combination= { "lt", "-ST", "t" },
utype = "mass",
},
["LT t ST"] = {
combination= { "lt", "t", "-ST" },
utype = "mass",
},
["ST LT t"] = {
combination= { "-ST", "lt", "t" },
utype = "mass",
},
["ST t LT"] = {
combination= { "-ST", "t", "lt" },
utype = "mass",
},
["t LT ST"] = {
combination= { "t", "lt", "-ST" },
utype = "mass",
},
["ton"] = {
combination= { "LT", "ST" },
utype = "mass",
},
["kPa kg/cm2"] = {
combination= { "kPa", "kgf/cm2" },
utype = "pressure",
},
["kPa lb/in2"] = {
combination= { "kPa", "-lb/in2" },
utype = "pressure",
},
["floz"] = {
combination= { "impoz", "USoz" },
utype = "volume",
},
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local default_exceptions = {
-- Prefixed units with a default different from that of the base unit.
-- Each key item is a prefixed symbol (unitcode for engineering notation).
["cm<sup>2</sup>"] = "sqin",
["dm<sup>2</sup>"] = "sqin",
["e3acre"] = "km2",
["e3m2"] = "e6sqft",
["e6acre"] = "km2",
["e6ha"] = "e6acre",
["e6km2"] = "e6sqmi",
["e6m2"] = "e6sqft",
["e6sqft"] = "v * 9.290304 < 100 ! e3 ! e6 ! m2",
["e6sqmi"] = "e6km2",
["hm<sup>2</sup>"] = "acre",
["km<sup>2</sup>"] = "sqmi",
["mm<sup>2</sup>"] = "sqin",
["aJ"] = "eV",
["e3BTU"] = "MJ",
["e6BTU"] = "GJ",
["EJ"] = "kWh",
["fJ"] = "keV",
["GJ"] = "kWh",
["MJ"] = "kWh",
["PJ"] = "kWh",
["pJ"] = "MeV",
["TJ"] = "kWh",
["YJ"] = "kWh",
["yJ"] = "μeV",
["ZJ"] = "kWh",
["zJ"] = "meV",
["e12cuft/a"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3/a",
["e12cuft/d"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3/d",
["e12m3/a"] = "Tcuft/a",
["e12m3/d"] = "Tcuft/d",
["e3cuft/a"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/a",
["e3cuft/d"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/d",
["e3cuft/s"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/s",
["e3m3/a"] = "v < 28.316846592 ! k ! M ! cuft/a",
["e3m3/d"] = "v < 28.316846592 ! k ! M ! cuft/d",
["e3m3/s"] = "v < 28.316846592 ! k ! M ! cuft/s",
["e3USgal/a"] = "v * 3.785411784 < 1000 ! ! e3 ! m3/a",
["e6cuft/a"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/a",
["e6cuft/d"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/d",
["e6cuft/s"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/s",
["e6m3/a"] = "v < 28.316846592 ! M ! G ! cuft/a",
["e6m3/d"] = "v < 28.316846592 ! M ! G ! cuft/d",
["e6m3/s"] = "v < 28.316846592 ! e6 ! e9 ! cuft/s",
["e6USgal/a"] = "v * 3.785411784 < 1000 ! e3 ! e6 ! m3/a",
["e9cuft/a"] = "m3/a",
["e9cuft/d"] = "v * 2.8316846592 < 100 ! e6 ! e9 ! m3/d",
["e9m3/a"] = "v < 28.316846592 ! G ! T ! cuft/a",
["e9m3/d"] = "v < 28.316846592 ! G ! T ! cuft/d",
["e9m3/s"] = "v < 28.316846592 ! e9 ! e12 ! cuft/s",
["e9USgal/a"] = "v * 3.785411784 < 1000 ! e6 ! e9 ! m3/a",
["e9USgal/s"] = "v * 3.785411784 < 1000 ! e6 ! e9 ! m3/s",
["nN"] = "gr-f",
["μN"] = "gr-f",
["mN"] = "oz-f",
["am"] = "in",
["cm"] = "in",
["dam"] = "ft",
["dm"] = "in",
["e12km"] = "e12mi",
["e12mi"] = "e12km",
["e3AU"] = "ly",
["e3km"] = "e3mi",
["e3mi"] = "e3km",
["e6km"] = "e6mi",
["e6mi"] = "e6km",
["e9km"] = "AU",
["e9mi"] = "e9km",
["Em"] = "mi",
["fm"] = "in",
["Gm"] = "mi",
["hm"] = "ft",
["km"] = "mi",
["mm"] = "in",
["Mm"] = "mi",
["nm"] = "in",
["Pm"] = "mi",
["pm"] = "in",
["Tm"] = "mi",
["Ym"] = "mi",
["ym"] = "in",
["Zm"] = "mi",
["zm"] = "in",
["μm"] = "in",
["e12lb"] = "v * 4.5359237 < 10 ! Mt ! Gt",
["e3lb"] = "v * 4.5359237 < 10 ! kg ! t",
["e3ozt"] = "v * 0.311034768 < 10 ! kg ! t",
["e3t"] = "LT ST",
["e6carat"] = "t",
["e6lb"] = "v * 4.5359237 < 10 ! t ! kilotonne",
["e6ozt"] = "lb kg",
["e6ST"] = "Mt",
["e6t"] = "LT ST",
["e9lb"] = "v * 4.5359237 < 10 ! kilotonne ! Mt",
["e9t"] = "LT ST",
["Gg"] = "lb",
["kg"] = "lb",
["mg"] = "gr",
["Mg"] = "LT ST",
["ng"] = "gr",
["μg"] = "gr",
["mBq"] = "fCi",
["kBq"] = "nCi",
["MBq"] = "μCi",
["GBq"] = "mCi",
["TBq"] = "Ci",
["PBq"] = "kCi",
["EBq"] = "kCi",
["fCi"] = "mBq",
["pCi"] = "Bq",
["nCi"] = "Bq",
["μCi"] = "kBq",
["mCi"] = "MBq",
["kCi"] = "TBq",
["MCi"] = "PBq",
["ns"] = "μs",
["μs"] = "ms",
["ms"] = "s",
["ks"] = "h",
["Ms"] = "week",
["Gs"] = "decade",
["Ts"] = "millennium",
["Ps"] = "million year",
["Es"] = "thousand million year",
["MK"] = "keVT",
["cL"] = "impoz usoz",
["cl"] = "impoz usoz",
["cm<sup>3</sup>"] = "cuin",
["dL"] = "impoz usoz",
["dl"] = "impoz usoz",
["mm<sup>3</sup>"] = "cuin",
["dm<sup>3</sup>"] = "cuin",
["e12cuft"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3",
["e12impgal"] = "v * 4.54609 < 1000 ! T ! P ! l",
["e12m3"] = "v < 28.316846592 ! T ! P ! cuft",
["e12U.S.gal"] = "v * 3.785411784 < 1000 ! T ! P ! l",
["e12USgal"] = "v * 3.785411784 < 1000 ! T ! P ! l",
["e15cuft"] = "v * 2.8316846592 < 100 ! e12 ! e15 ! m3",
["e15m3"] = "Pcuft",
["e3bdft"] = "v * 0.23597372167 < 100 ! e3 ! e6 ! m3",
["e3cuft"] = "v * 2.8316846592 < 100 ! ! e3 ! m3",
["e3impgal"] = "v * 4.54609 < 1000 ! k ! M ! l",
["e3m3"] = "v < 28.316846592 ! k ! M ! cuft",
["e3U.S.gal"] = "v * 3.785411784 < 1000 ! k ! M ! l",
["e3USgal"] = "v * 3.785411784 < 1000 ! k ! M ! l",
["e6bdft"] = "v * 0.23597372167 < 100 ! e3 ! e6 ! m3",
["e6cuft"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3",
["e6cuyd"] = "v * 7.64554857984 < 10 ! e3 ! e6 ! m3",
["e6impgal"] = "v * 4.54609 < 1000 ! M ! G ! l",
["e6L"] = "USgal",
["e6m3"] = "v < 28.316846592 ! M ! G ! cuft",
["e6U.S.gal"] = "v * 3.785411784 < 1000 ! M ! G ! l",
["e6USgal"] = "v * 3.785411784 < 1000 ! M ! G ! l",
["e9bdft"] = "v * 0.23597372167 < 100 ! e6 ! e9 ! m3",
["e9cuft"] = "v * 2.8316846592 < 100 ! e6 ! e9 ! m3",
["e9impgal"] = "v * 4.54609 < 1000 ! G ! T ! l",
["e9m3"] = "v < 28.316846592 ! G ! T ! cuft",
["e9U.S.gal"] = "v * 3.785411784 < 1000 ! G ! T ! l",
["e9USgal"] = "v * 3.785411784 < 1000 ! G ! T ! l",
["GL"] = "cuft",
["Gl"] = "cuft",
["kL"] = "cuft",
["kl"] = "cuft",
["km<sup>3</sup>"] = "cumi",
["mL"] = "impoz usoz",
["ml"] = "impoz usoz",
["Ml"] = "v < 28.316846592 ! e3 ! e6 ! cuft",
["ML"] = "v < 28.316846592 ! e3 ! e6 ! cuft",
["TL"] = "cumi",
["Tl"] = "cumi",
["μL"] = "cuin",
["μl"] = "cuin",
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local link_exceptions = {
-- Prefixed units with a linked article different from that of the base unit.
-- Each key item is a prefixed symbol (not unitcode).
["mm<sup>2</sup>"] = "Square millimetre",
["cm<sup>2</sup>"] = "Square centimetre",
["dm<sup>2</sup>"] = "Square decimetre",
["km<sup>2</sup>"] = "Square kilometre",
["kJ"] = "Kilojoule",
["MJ"] = "Megajoule",
["GJ"] = "Gigajoule",
["TJ"] = "Terajoule",
["fm"] = "Femtometre",
["pm"] = "Picometre",
["nm"] = "Nanometre",
["μm"] = "Micrometre",
["mm"] = "Millimetre",
["cm"] = "Centimetre",
["dm"] = "Decimetre",
["dam"] = "Decametre",
["hm"] = "Hectometre",
["km"] = "Kilometre",
["Mm"] = "Megametre",
["Gm"] = "Gigametre",
["Tm"] = "Terametre",
["Pm"] = "Petametre",
["Em"] = "Exametre",
["Zm"] = "Zettametre",
["Ym"] = "Yottametre",
["μg"] = "Microgram",
["mg"] = "Milligram",
["kg"] = "Kilogram",
["Mg"] = "Tonne",
["yW"] = "Yoctowatt",
["zW"] = "Zeptowatt",
["aW"] = "Attowatt",
["fW"] = "Femtowatt",
["pW"] = "Picowatt",
["nW"] = "Nanowatt",
["μW"] = "Microwatt",
["mW"] = "Milliwatt",
["kW"] = "Kilowatt",
["MW"] = "Megawatt",
["GW"] = "Gigawatt",
["TW"] = "Terawatt",
["PW"] = "Petawatt",
["EW"] = "Exawatt",
["ZW"] = "Zettawatt",
["YW"] = "Yottawatt",
["as"] = "Attosecond",
["fs"] = "Femtosecond",
["ps"] = "Picosecond",
["ns"] = "Nanosecond",
["μs"] = "Microsecond",
["ms"] = "Millisecond",
["ks"] = "Kilosecond",
["Ms"] = "Megasecond",
["Gs"] = "Gigasecond",
["Ts"] = "Terasecond",
["Ps"] = "Petasecond",
["Es"] = "Exasecond",
["Zs"] = "Zettasecond",
["Ys"] = "Yottasecond",
["mm<sup>3</sup>"] = "Cubic millimetre",
["cm<sup>3</sup>"] = "Cubic centimetre",
["dm<sup>3</sup>"] = "Cubic decimetre",
["dam<sup>3</sup>"] = "Cubic decametre",
["km<sup>3</sup>"] = "Cubic kilometre",
["μL"] = "Microlitre",
["μl"] = "Microlitre",
["mL"] = "Millilitre",
["ml"] = "Millilitre",
["cL"] = "Centilitre",
["cl"] = "Centilitre",
["dL"] = "Decilitre",
["dl"] = "Decilitre",
["daL"] = "Decalitre",
["dal"] = "Decalitre",
["hL"] = "Hectolitre",
["hl"] = "Hectolitre",
["kL"] = "Kilolitre",
["kl"] = "Kilolitre",
["ML"] = "Megalitre",
["Ml"] = "Megalitre",
["GL"] = "Gigalitre",
["Gl"] = "Gigalitre",
["TL"] = "Teralitre",
["Tl"] = "Teralitre",
["PL"] = "Petalitre",
["Pl"] = "Petalitre",
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local per_unit_fixups = {
-- Automatically created per units of form "x/y" may have their unit type
-- changed, for example, "length/time" is changed to "speed".
-- Other adjustments can also be specified.
["/area"] = "per unit area",
["/volume"] = "per unit volume",
["area/area"] = "area per unit area",
["energy/length"] = "energy per unit length",
["energy/mass"] = "energy per unit mass",
["energy/time"] = { utype = "power", link = "Power (physics)" },
["energy/volume"] = "energy per unit volume",
["force/area"] = { utype = "pressure", link = "Pressure" },
["length/length"] = { utype = "gradient", link = "Grade (slope)" },
["length/time"] = { utype = "speed", link = "Speed" },
["length/time/time"] = { utype = "acceleration", link = "Acceleration" },
["mass/area"] = { utype = "pressure", multiplier = 9.80665 },
["mass/length"] = "linear density",
["mass/mass"] = "concentration",
["mass/power"] = "mass per unit power",
["mass/time"] = "mass per unit time",
["mass/volume"] = { utype = "density", link = "Density" },
["power/mass"] = "power per unit mass",
["power/volume"] = { link = "Power density" },
["pressure/length"] = "fracture gradient",
["speed/time"] = { utype = "acceleration", link = "Acceleration" },
["volume/area"] = "volume per unit area",
["volume/length"] = "volume per unit length",
["volume/time"] = "flow",
}
return {
all_units = all_units,
default_exceptions = default_exceptions,
link_exceptions = link_exceptions,
per_unit_fixups = per_unit_fixups,
}
df9e48c56b5ed9957eaef10e36df353b161075f5
Module:Convert/text
828
48
111
2022-02-13T04:01:17Z
Canopus >Johnuniq
0
update from sandbox per [[Template talk:Convert#Module version 27]]
Scribunto
text/plain
-- Text used by Module:Convert for enwiki.
-- This is a separate module to simplify translation for use on another wiki.
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
-- Some units accept an SI prefix before the unit code, such as "kg" for kilogram.
local SIprefixes = {
-- The prefix field is what the prefix should be, if different from the prefix used.
['Y'] = { exponent = 24, name = 'yotta', },
['Z'] = { exponent = 21, name = 'zetta', },
['E'] = { exponent = 18, name = 'exa' , },
['P'] = { exponent = 15, name = 'peta' , },
['T'] = { exponent = 12, name = 'tera' , },
['G'] = { exponent = 9, name = 'giga' , },
['M'] = { exponent = 6, name = 'mega' , },
['k'] = { exponent = 3, name = 'kilo' , },
['h'] = { exponent = 2, name = 'hecto', },
['da']= { exponent = 1, name = 'deca' , name_us = 'deka' },
['d'] = { exponent = -1, name = 'deci' , },
['c'] = { exponent = -2, name = 'centi', },
['m'] = { exponent = -3, name = 'milli', },
['μ'] = { exponent = -6, name = 'micro', }, -- key = 'GREEK SMALL LETTER MU' (U+03BC) utf-8 CE BC
['µ'] = { exponent = -6, name = 'micro', prefix = 'μ' }, -- key = 'MICRO SIGN' (U+00B5) utf-8 C2 B5
['u'] = { exponent = -6, name = 'micro', prefix = 'μ' }, -- not an SI prefix, but allow for people typing this
['n'] = { exponent = -9, name = 'nano' , },
['p'] = { exponent =-12, name = 'pico' , },
['f'] = { exponent =-15, name = 'femto', },
['a'] = { exponent =-18, name = 'atto' , },
['z'] = { exponent =-21, name = 'zepto', },
['y'] = { exponent =-24, name = 'yocto', },
}
-- Some units can be qualified with one of the following prefixes, when linked.
local customary_units = {
{ "US", link = "United States customary units" },
{ "U.S.", link = "United States customary units" },
{ "imperial", link = "Imperial units" },
{ "imp", link = "Imperial units" },
}
-- Names when using engineering notation (a prefix of "eN" where N is a number; example "e6km").
-- key = { "name", link = "article title", exponent = numeric_key_value }
-- If lk=on and link is defined, the name of the number will appear as a link.
local eng_scales = {
["3"] = { "thousand", exponent = 3 },
["6"] = { "million", exponent = 6 },
["9"] = { "billion", link = "1000000000 (number)", exponent = 9 },
["12"] = { "trillion", link = "1000000000000 (number)", exponent = 12 },
["15"] = { "quadrillion", link = "1000000000000000 (number)", exponent = 15 },
}
local all_categories = {
unit = "[[Category:Convert errors]]",
option = "[[Category:Convert errors]]",
warning = '[[Category:Convert invalid options]]',
tracking = '[[Category:Convert tracking]]',
}
-- For some error messages, the following puts the wanted style around
-- each unit code marked like '...%{ft%}...'.
local unitcode_regex = '%%([{}])'
local unitcode_replace = { ['{'] = '"', ['}'] = '"' } -- no longer need the more elaborate substitute used before 2013-09-28
-- All messages that may be displayed if a problem occurs.
local all_messages = {
-- Message format string: $1=title, $2=text, $3=category, $4=anchor.
-- Each displayed message starts with "Convert:" so can easily locate by searching article.
cvt_format = '<sup class="noprint Inline-Template" style="white-space:nowrap;">[<i>[[Help:Convert messages#$4|<span title="Convert: $1">convert: $2</span>]]</i>]</sup>$3<span class="error"></span>',
cvt_format2 = '<sup class="noprint Inline-Template" style="white-space:nowrap;">[[Help:Convert messages#$4|<span title="Convert: $1">$2</span>]]</sup>$3<span class="error"></span>',
cvt_format_preview = '<strong class="error">Error in convert: $1 [[Help:Convert messages#$4|(help)]]</strong>$3',
-- Each of following messages is a table:
-- { [1] = 'title', -- mouseover title text
-- [2] = 'text', -- link text displayed in article
-- [3] = 'category key', -- key to lookup category in all_categories
-- [4] = 'anchor', -- anchor for link to relevant section on help page
-- regex = gsub_regex,
-- replace = gsub_table,
-- } Mouseover title text Link text CatKey Anchor
cvt_bad_input = { 'input "$1" must be a number and unit' , 'invalid input' , 'option', 'invalid_input' },
cvt_bad_num = { 'Value "$1" must be a number' , 'invalid number' , 'option', 'invalid_number' },
cvt_big_prec = { 'Precision "$1" is too large' , 'precision too large' , 'option', 'precision_too_large' },
cvt_invalid_num = { 'Number has overflowed' , 'number overflow' , 'option', 'number_overflow' },
cvt_no_num = { 'Needs the number to be converted' , 'needs a number' , 'option', 'needs_number' },
cvt_no_num2 = { 'Needs another number for a range' , 'needs another number', 'option', 'needs_another_number' },
cvt_bad_altitude = { '"$1" needs an integer' , 'invalid altitude' , 'option', 'invalid_altitude' },
cvt_bad_frac = { '"$1" needs an integer above 1' , 'invalid fraction' , 'option', 'invalid_fraction' },
cvt_bad_prec = { 'Precision "$1" must be an integer' , 'invalid precision' , 'option', 'invalid_precision' },
cvt_bad_sigfig = { '"$1" needs a positive integer' , 'invalid sigfig' , 'option', 'invalid_sigfig' },
cvt_empty_option = { 'Ignored empty option "$1"' , 'empty option' , 'option', 'empty_option' },
cvt_deprecated = { 'Option "$1" is deprecated' , '*' , 'option', 'deprecated_option', format = 'cvt_format2', nowarn = true },
cvt_no_spell = { 'Spelling is not available' , 'bug, ask for help' , 'option', 'ask_for_help' },
cvt_unknown_option = { 'Ignored invalid option "$1"' , 'invalid option' , 'option', 'invalid_option' },
cvt_wd_fail = { 'Unable to access Wikidata' , 'wikidata problem' , 'option', 'wikidata_problem' },
cvt_bad_default = { 'Unit "$1" has an invalid default' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_bad_unit = { 'Unit "$1" is invalid here' , 'unit invalid here' , 'unit' , 'unit_invalid_here' },
cvt_no_default = { 'Unit "$1" has no default output unit' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_no_unit = { 'Needs name of unit' , 'needs unit name' , 'unit' , 'needs_unit_name' },
cvt_unknown = { 'Unit name "$1" is not known' , 'unknown unit' , 'unit' , 'unknown_unit' },
cvt_should_be = { '$1' , 'ambiguous unit' , 'unit' , 'ambiguous_unit', regex = unitcode_regex, replace = unitcode_replace },
cvt_mismatch = { 'Cannot convert "$1" to "$2"' , 'unit mismatch' , 'unit' , 'unit_mismatch' },
cvt_bug_convert = { 'Bug: Cannot convert between specified units', 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_lookup = { 'Unit "$1" is incorrectly defined' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
}
-- Text to join input value/unit with output value/unit.
local disp_joins = {
-- [1]=before output, [2]=after output, [3]=between outputs in a combination; default "; "
-- [wantname] gives default abbr=off
["or"] = { " or " , "" , " or ", wantname = true },
["sqbr-sp"] = { " [" , "]" },
["sqbr-nbsp"] = { " [" , "]" },
["comma"] = { ", " , "" , ", " },
["slash-sp"] = { " / " , "" , wantname = true },
["slash-nbsp"] = { " / ", "" , wantname = true },
["slash-nosp"] = { "/" , "" , wantname = true },
["b"] = { " (" , ")" },
["(or)"] = { " (" , ")", " or " },
["br"] = { "<br />" , "" , wantname = true },
["br()"] = { "<br />(" , ")", wantname = true },
}
-- Text to separate values in a range.
local range_types = {
-- Specifying a table requires either:
-- * "off" and "on" values (for "abbr=off" and "abbr=on"), or
-- * "input" and "output" values (for LHS and RHS);
-- other fields are optional.
-- When "adj=on|abbr=off" applies, spaces in range text are replaced with hyphens.
-- With "exception = true", that also occurs with "adj=on|abbr=on".
-- If "adj" is defined here, that text (unchanged) is used with "adj=on".
["+"] = " + ",
[","] = ", ",
[", and"] = ", and ",
[", or"] = ", or ",
["by"] = " by ",
["-"] = "–",
["to about"] = " to about ",
["and"] = { off = " and ", on = " and ", exception = true },
["and(-)"] = { input = " and ", output = "–" },
["or"] = { off = " or " , on = " or " , exception = true },
["to"] = { off = " to " , on = " to " , exception = true },
["to(-)"] = { input = " to ", output = "–" },
["+/-"] = { off = " ± ", on = " ± ", adj = " ± ", is_range_change = true },
["by(x)"] = { input = " by ", output = " × ", out_range_x = true },
["x"] = { off = " by ", on = " × ", abbr_range_x = true },
["xx"] = " × ",
["*"] = "×",
["/"] = " / ", -- for a table of high/low temperatures with {{convert|83|/|63|F|disp=br()|abbr=values}}
}
local range_aliases = {
-- ["alternative name for a range"] = "standard range name"
["–"] = "-",
["–"] = "-",
["×"] = "x",
["×"] = "x",
["±"] = "+/-",
["±"] = "+/-",
}
-- Convert accepts range text delimited with whitespace, for example, {{convert|1 to 2|ft}}.
-- In addition, the following "words" are accepted without spaces, for example, {{convert|1-2|ft}}.
-- Words must be in correct order for searching, for example, 'x' after 'xx'.
local range_words = { '-', '–', 'xx', 'x', '*' }
local ranges = {
types = range_types,
aliases = range_aliases,
words = range_words,
}
-- Valid option names.
local en_option_name = {
-- ["local text for option name"] = "en name used in this module"
["$"] = "$",
["abbr"] = "abbr",
["adj"] = "adj",
["altitude_ft"] = "altitude_ft",
["altitude_m"] = "altitude_m",
["comma"] = "comma",
["debug"] = "debug",
["disp"] = "disp",
["frac"] = "frac",
["input"] = "input",
["lang"] = "lang",
["lk"] = "lk",
["order"] = "order",
["qid"] = "qid",
["qual"] = "qual",
["qualifier"] = "qual",
["round"] = "round",
["sigfig"] = "sigfig",
["sing"] = "adj", -- "sing" is an old alias for "adj"
["sortable"] = "sortable",
["sp"] = "sp",
["spell"] = "spell",
["stylein"] = "stylein",
["styleout"] = "styleout",
["tracking"] = "tracking",
}
-- Valid option values.
-- Convention: parms.opt_xxx refers to an option that is set here
-- (not intended to be set by the template which invokes this module).
-- Example: At enwiki, "abbr" includes:
-- ["values"] = "opt_values"
-- As a result, if the template uses abbr=values, Module:Convert sets:
-- parms["opt_values"] = true
-- parms["abbr"] = nil
-- Therefore parms.abbr will be nil, or will have one of the listed values
-- that do not start with "opt_".
-- An option value of form "xxx?" is the same as "xxx" but shows the input as deprecated.
local en_option_value = {
["$"] = 'TEXT', -- TEXT should be a currency symbol that will be used instead of "$"
["abbr"] = {
-- ["local text for option value"] = "en value used in this module"
["def"] = "", -- ignored (some wrapper templates call convert with "abbr=def" to mean "default abbreviation")
["h"] = "on", -- abbr=on + use "h" for hand unit (default)
["hh"] = "opt_hand_hh", -- abbr=on + use "hh" for hand unit
["in"] = "in", -- use symbol for LHS unit
["none"] = "off", -- old name for "off"
["off"] = "off", -- use name for all units
["on"] = "on", -- use symbol for all units
["out"] = "out", -- use symbol for RHS unit (default)
["unit"] = "unit", -- abbr=on but abbreviate units only: e6km → million km (not ×10⁶ km)
["values"] = "opt_values", -- show only input and output numbers, not units
["~"] = "opt_also_symbol", -- show input unit symbol as well as name
},
["adj"] = {
["mid"] = "opt_adjectival, opt_adj_mid", -- adj=on with user-specified text after input unit (between input and output)
["off"] = "", -- ignored (off is the default)
["on"] = "opt_adjectival", -- unit name is singular and hyphenated
["pre"] = "opt_one_preunit", -- user-specified text before input unit
["ri0"] = "opt_ri=0", -- round input with precision = 0
["ri1"] = "opt_ri=1", -- round input with precision = 1
["ri2"] = "opt_ri=2", -- round input with precision = 2
["ri3"] = "opt_ri=3", -- round input with precision = 3
},
["altitude_ft"] = 'INTEGER',
["altitude_m"] = 'INTEGER',
["comma"] = {
["5"] = "opt_comma5", -- only use numsep grouping if 5 or more digits
["gaps"] = "opt_gaps", -- use gaps, not numsep, to separate groups of digits
["gaps3"] = "opt_gaps, opt_gaps3", -- group only in threes rather than default of no gap before a single digit after decimal mark
["off"] = "opt_nocomma", -- no numsep in input or output numbers
},
["debug"] = {
["yes"] = "opt_sortable_debug", -- make the normally hidden sort key visible
},
["disp"] = {
["5"] = "opt_round=5?", -- round output value to nearest 5
["b"] = "b", -- join: '(...)'
["(or)"] = "(or)", -- join: '(...)' with 'or' between outputs in a combination
["br"] = "br", -- join: '<br />'
["br()"] = "br()", -- join: '<br />(...)'
["comma"] = "comma", -- join: ','
["flip"] = "opt_flip", -- reverse order of input/output
["number"] = "opt_output_number_only", -- display output value (not input, and not output symbol/name)
["or"] = "or", -- join: 'or'
["out"] = "opt_output_only",
["output number only"] = "opt_output_number_only",
["output only"] = "opt_output_only",
["preunit"] = "opt_two_preunits", -- user-specified text before input and output units
["sqbr"] = "sqbr", -- join: '[...]'
["table"] = "opt_table", -- output is suitable for a table cell with align="right"
["tablecen"] = "opt_tablecen", -- output is suitable for a table cell with align="center"
["unit"] = "opt_input_unit_only", -- display input symbol/name (not output, and not input value)
["unit or text"] = "opt_input_unit_only, opt_ignore_error", -- display input symbol/name, or given unit code if not known
["unit2"] = "opt_output_unit_only",
["x"] = "x", -- join: <first>...<second> (user-specified text)
},
["frac"] = 'INTEGER',
["input"] = 'TEXT', -- TEXT should be value><space><unitcode> or <wikidata-property-id>
["lang"] = { -- language for output digits (both en and local digits are always accepted for input)
["en"] = "opt_lang_en", -- use en digits for numbers, regardless of local language
["local"] = "opt_lang_local", -- use local digits for numbers (default, although config can change default to en)
},
["lk"] = {
["in"] = "in", -- link LHS unit name or symbol
["off"] = "off", -- do not link: same as default except for hand unit
["on"] = "on", -- link all unit names or symbols (but not twice for the same unit)
["out"] = "out", -- link RHS unit name or symbol
},
["order"] = {
["flip"] = "opt_flip", -- reverse order of input/output
["out"] = "opt_order_out", -- do not show input; instead, use order in output combination, with the first output shown as the input
},
["qid"] = 'TEXT', -- TEXT should be a Wikidata Q item identifier
["qual"] = 'TEXT', -- TEXT should be a Wikidata Q item identifier
["round"] = {
["0.5"] = "opt_round=0.5", -- round output value to nearest 0.5
["5"] = "opt_round=5", -- round output value to nearest 5
["10"] = "opt_round=10", -- round output value to nearest 10 (same as but clearer than "|-1")
["25"] = "opt_round=25", -- round output value to nearest 25
["50"] = "opt_round=50", -- round output value to nearest 50
["each"] = "opt_round_each", -- using default precision in a range, round each output separately (default uses highest precision of each item in range)
},
["sigfig"] = 'INTEGER',
["sortable"] = {
["off"] = "", -- ignored (off is the default)
["on"] = "opt_sortable_on", -- output sort key for use in a sortable table, based on value from converting to a standard base unit
["debug"] = "opt_sortable_on, opt_sortable_debug", -- |sortable=debug is the same as |sortable=on|debug=yes
},
["sp"] = {
["us"] = "opt_sp_us", -- use U.S. spelling (like "meter" instead of default "metre")
},
["spell"] = { -- only English spelling is supported; not scientific notation; only some fractions
["in"] = "opt_spell_in", -- spell input value in words
["In"] = "opt_spell_in, opt_spell_upper", -- spell input value in words with first letter uppercase
["on"] = "opt_spell_in, opt_spell_out", -- spell input and output values in words
["On"] = "opt_spell_in, opt_spell_out, opt_spell_upper", -- same, with first letter of first word in result uppercase
},
["stylein"] = 'TEXT',
["styleout"] = 'TEXT',
["tracking"] = 'TEXT',
}
local titles = {
["frac"] = "Fraction/styles.css",
["sfrac"] = "Sfrac/styles.css",
}
return {
SIprefixes = SIprefixes,
all_categories = all_categories,
all_messages = all_messages,
currency = { ['$'] = true, ['£'] = true, ['€'] = true, ['₱'] = true, ['₽'] = true, ['¥'] = true },
customary_units = customary_units,
disp_joins = disp_joins,
en_option_name = en_option_name,
en_option_value = en_option_value,
eng_scales = eng_scales,
ranges = ranges,
titles = titles,
}
05665ce7dee224b4474fd898266e157aab84691f
Template:End
10
144
303
2022-02-20T11:17:15Z
Canopus >Gonnym
0
Undid revision 1072975485 by [[Special:Contributions/Gonnym|Gonnym]] ([[User talk:Gonnym|talk]])
wikitext
text/x-wiki
<includeonly>
{{#if:{{{html|}}}|</table>|{{!}}} }}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using end template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:End]] with unknown parameter "_VALUE_"|ignoreblank=y| html | 1<!--parameter does not do anything, but described in the documentation since 2015--> }}<noinclude>{{Documentation}}</noinclude>
6da317c960412bc7ac63866ddd9237d1a9bd914e
Module:Check for unknown parameters
828
70
155
2022-02-21T05:24:13Z
Canopus >BusterD
0
Changed protection settings for "[[Module:Check for unknown parameters]]": [[WP:High-risk templates|Highly visible template]]; requested at [[WP:RfPP]] ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '<' .. tag .. '>...</' .. tag .. '>')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
return table.concat(res)
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
return p
93db6d115d4328d2a5148bb42959105e367b663e
Module:ResolveEntityId
828
92
199
2022-03-03T02:11:37Z
Canopus >Ahecht
0
Sync from sandbox. Follow Wikipedia redirects, remove _entityid() function. Feel free to revert if any more issues crop up.
Scribunto
text/plain
local p = {}
function p._id(idOrTitle, alt)
local function checkId(id)
if id and mw.wikibase.entityExists(id) then
local sitelink = mw.wikibase.getSitelink(id)
if sitelink then
return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(id).id
end
return mw.wikibase.getEntity(id).id
else
return alt
end
end
if type(idOrTitle) == 'string' then
idOrTitle = mw.ustring.upper(mw.ustring.sub(idOrTitle, 1, 1)) .. mw.ustring.sub(idOrTitle, 2)
if mw.wikibase.isValidEntityId(idOrTitle) then
-- idOrTitle is in the proper format for a Wikidata entity ID
return checkId(idOrTitle)
else
local eid = mw.wikibase.getEntityIdForTitle(idOrTitle)
if eid then
-- idOrTitle is a title that matches a Wikidata entity
local instanceOf = mw.wikibase.getBestStatements(eid, 'P31')[1] --instance of
if not instanceOf or instanceOf.mainsnak.datavalue.value.id ~= 'Q4167410' then
-- instance-of value is missing or is not "disambiguation"
return checkId(eid)
end
else
-- idOrTitle is a title, but no wikidata item exists for that title
local rtarget = mw.title.new(idOrTitle).redirectTarget
if rtarget then
-- title is a Wikipedia redirect
return p._id(rtarget.fullText, alt)
end
end
end
end
return alt
end
function p.entityid(frame)
return p._id(frame.args[1], frame.args[2])
end
return p
520d9c0247df2692f8909c86f05c6eb7aab182c0
Template:Starbox astrometry
10
152
319
2022-04-03T19:25:52Z
Canopus >Paine Ellsworth
0
per edit requests on talk page - footnote placements + remove all instances of the "small" tag to improve accessibility
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||[[Astrometry]]}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}</th></tr><!--
--><tr><th colspan="2" style="text-align: center">{{{component1<includeonly>|</includeonly>}}}</tr><!--
-->{{#if:{{{radial_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Radial velocity]] (R<sub>v</sub>)'''</td><td>{{{radial_v}}} km/s</td></tr>}}<!--
-->{{#if:{{{total_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''Total velocity'''</td><td>{{{total_v}}} km/s</td></tr>}}<!--
-->{{#if:{{{prop_mo_ra<includeonly>|</includeonly>}}}{{{prop_mo_dec|}}}|<tr style="vertical-align:top;"><td>'''[[Proper motion]] (μ)'''</td><td> <abbr title="Right Ascension">RA:</abbr> {{{prop_mo_ra|}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote|}}} <br /> <abbr title="Declination">Dec.:</abbr> {{{prop_mo_dec|}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote|}}} </td></tr> }}<!--
-->{{#if:{{{parallax<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Stellar parallax|Parallax]] (π)'''</td><td>{{{parallax}}}{{#if:{{{p_error|}}}| ± {{{p_error}}} }} [[Milliarcsecond|mas]]{{#if:{{{parallax_footnote|}}}|{{{parallax_footnote}}} }}</td></tr>}}<!--
-->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}{{{dist_pc|}}}{{#if:{{{parallax|}}}|{{#if:{{{p_error|}}}|{{#ifexpr: {{{parallax|}}}-{{{p_error|}}}>0|yes}}}}}}|<tr style="vertical-align:top;"><td>'''[[Distance (astronomy)|Distance]]'''</td><!--
--><td><!--
-->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}{{{dist_pc|}}}||{{ErrorBar2|{{#expr: 3261.5638 / {{{parallax}}} }}|{{#if:{{{p_error|}}}|{{#expr: 3261.5638 * {{{p_error}}} / ({{{parallax}}} * {{{parallax}}}) }} }}|0.1}} [[Light-year|ly]] <br />({{ErrorBar2|{{#expr: 1000.0 / {{{parallax}}} }}|{{#if:{{{p_error|}}}|{{#expr: 1000.0 * {{{p_error}}} / ({{{parallax}}} * {{{parallax}}}) }} }}|0.1}} [[Parsec|pc]])}}<!-- -->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}|{{{dist_ly}}} [[Light-year|ly]] {{#if:{{{dist_pc|}}}|<br />({{{dist_pc}}} [[Parsec|pc]])}}|{{#if:{{{dist_pc|}}}|{{{dist_pc}}} [[Parsec|pc]]}}}}{{{dist_footnote|}}}<!--
--></td></tr>}}<!--
-->{{#if:{{{absmag_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute magnitude]] (M<sub>V</sub>)'''</td><td>{{{absmag_v}}}</td></tr>}}<!--
-->{{#if:{{{absmag_bol<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute bolometric<br>magnitude]] (M<sub>bol</sub>)'''</td><td>{{{absmag_bol}}}</td></tr>}}<!--
--><tr><th colspan="2" style="text-align: center">{{{component2<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{radial_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Radial velocity]] (R<sub>v</sub>)'''</td><td>{{{radial_v2}}} km/s</td></tr>}}<!--
-->{{#if:{{{total_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''Total velocity'''</td><td>{{{total_v2}}} km/s</td></tr>}}<!--
-->{{#if:{{{prop_mo_ra2<includeonly>|</includeonly>}}}{{{prop_mo_dec2|}}}|<tr style="vertical-align:top;"><td>'''[[Proper motion]] (μ)'''</td><td> <abbr title="Right Ascension">RA:</abbr> {{{prop_mo_ra2|-}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote2|}}} <br /> <abbr title="Declination">Dec.:</abbr> {{{prop_mo_dec2|-}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote2|}}} </td></tr> }}<!--
-->{{#if:{{{parallax2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Stellar parallax|Parallax]] (π)'''</td><td>{{{parallax2}}}{{#if:{{{p_error2|}}}| ± {{{p_error2}}}}} [[Milliarcsecond|mas]]{{#if:{{{parallax_footnote2|}}}|{{{parallax_footnote2}}}}}</td></tr>}}<!--
-->{{#if:{{{dist_ly2<includeonly>|</includeonly>}}}{{{dist_pc2|}}}{{{parallax2|}}}|<tr style="vertical-align:top;"><td>'''[[Distance (astronomy)|Distance]]'''</td><!--
--><td><!--
-->{{#if:{{{dist_ly2<includeonly>|</includeonly>}}}{{{dist_pc2|}}}||{{ErrorBar2|{{#expr: 3261.5638 / {{{parallax2}}} }}|{{#if:{{{p_error2|}}}|{{#expr: 3261.5638 * {{{p_error2}}} / ({{{parallax2}}} * {{{parallax2}}}) }} }}|0.1}} [[Light-year|ly]] <br />({{ErrorBar2|{{#expr: 1000.0 / {{{parallax2}}} }}|{{#if:{{{p_error2|}}}|{{#expr: 1000.0 * {{{p_error2}}} / ({{{parallax2}}} * {{{parallax2}}}) }} }}|0.1}} [[Parsec|pc]])}}<!-- -->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}|{{{dist_ly2}}} [[Light-year|ly]] {{#if:{{{dist_pc2|}}}|<br />({{{dist_pc2}}} [[Parsec|pc]])}}|{{#if:{{{dist_pc2|}}}|{{{dist_pc2}}} [[Parsec|pc]]}}}}<!--
--></td></tr>}}<!-- -->{{#if:{{{absmag_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute magnitude]] (M<sub>V</sub>)'''</td><td>{{{absmag_v2}}}</td></tr>}}<!-- -->{{#if:{{{absmag_bol2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute bolometric<br>magnitude]] (M<sub>bol</sub>)'''</td><td>{{{absmag_bol2}}}</td></tr>}}<noinclude>
|}
{{Documentation}}
</noinclude>
e92454f250713fd8ce29da215c7da5e8ac87b802
Template:If empty
10
93
201
2022-04-03T20:56:41Z
Canopus >Wugapodes
0
Changed protection settings for "[[Template:If empty]]": [[WP:High-risk templates|Highly visible template]]: used on 2 million pages and permanently cascade protected; matches module protection ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:If empty|main}}<noinclude>{{Documentation}}</noinclude>
745940b7bdde8a1585c887ee4ee5ce81d98461a4
Template:Starbox character
10
155
325
2022-04-04T18:15:01Z
Canopus >Paine Ellsworth
0
per edit request at [[Template talk:Starbox begin#Template-protected edit request on 3 April 2022]] - remove small tags
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude>
|-
! style="background-color: #FFFFC0; text-align: center;" colspan="2"| {{#if:{{{no_heading|}}}||Characteristics}}
|-
{{#if:{{{component|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component}}}
}}
|-
{{#if:{{{component1|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component1}}}
}}
|- style="vertical-align:top"
{{#if:{{{type|}}}|
! style="text-align:left" {{!}} [[Stellar evolution|Evolutionary stage]]
{{!}} {{{type}}}
}}
|- style="vertical-align:top"
{{#if:{{{class|}}}|
! style="text-align:left" {{!}} [[Stellar classification|Spectral type]]
{{!}} {{{class}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_1_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude]] ({{{appmag_1_passband|}}})
{{!}} {{{appmag_1}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_2_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_2_passband|}}})
{{!}} {{{appmag_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_3_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_3_passband|}}})
{{!}} {{{appmag_3}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_4_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_4_passband|}}})
{{!}} {{{appmag_4}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_5_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_5_passband|}}})
{{!}} {{{appmag_5}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_6_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_6_passband|}}})
{{!}} {{{appmag_6}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_7_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_7_passband|}}})
{{!}} {{{appmag_7}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_8_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_8_passband|}}})
{{!}} {{{appmag_8}}}
}}
|- style="vertical-align:top"
{{#if:{{{u-b|}}}|
! style="text-align:left" {{!}} U−B {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{u-b}}}
}}
|- style="vertical-align:top"
{{#if:{{{b-v|}}}|
! style="text-align:left" {{!}} B−V {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{b-v}}}
}}
|- style="vertical-align:top"
{{#if:{{{v-r|}}}|
! style="text-align:left" {{!}} V−R {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{v-r}}}
}}
|- style="vertical-align:top"
{{#if:{{{r-i|}}}|
! style="text-align:left" {{!}} R−I {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{r-i}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-h|}}}|
! style="text-align:left" {{!}} J−H {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-h}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-k|}}}|
! style="text-align:left" {{!}} J−K {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-k}}}
}}
|- style="vertical-align:top"
{{#if:{{{variable|}}}|
! style="text-align:left" {{!}} [[Variable star|Variable type]]
{{!}} {{{variable}}}
}}
|- style="vertical-align:top"
{{#if:{{{component2|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component2}}}
}}
|- style="vertical-align:top"
{{#if:{{{type2|}}}|
! style="text-align:left" {{!}} [[Stellar evolution|Evolutionary stage]]
{{!}} {{{type2}}}
}}
|- style="vertical-align:top"
{{#if:{{{class2|}}}|
! style="text-align:left" {{!}} [[Stellar classification|Spectral type]]
{{!}} {{{class2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_1_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude]] ({{{appmag_1_passband2|}}})
{{!}} {{{appmag_1_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_2_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_2_passband2|}}})
{{!}} {{{appmag_2_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_3_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_3_passband2|}}})
{{!}} {{{appmag_3_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_4_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_4_passband2|}}})
{{!}} {{{appmag_4_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_5_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_5_passband2|}}})
{{!}} {{{appmag_5_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_6_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_6_passband2|}}})
{{!}} {{{appmag_6_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_7_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_7_passband2|}}})
{{!}} {{{appmag_7_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_8_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_8_passband2|}}})
{{!}} {{{appmag_8_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{u-b2|}}}|
! style="text-align:left" {{!}} U−B {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{u-b2}}}
}}
|- style="vertical-align:top"
{{#if:{{{b-v2|}}}|
! style="text-align:left" {{!}} B−V {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{b-v2}}}
}}
|- style="vertical-align:top"
{{#if:{{{v-r2|}}}|
! style="text-align:left" {{!}} V−R {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{v-r2}}}
}}
|- style="vertical-align:top"
{{#if:{{{r-i2|}}}|
! style="text-align:left" {{!}} R−I {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{r-i2}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-h2|}}}|
! style="text-align:left" {{!}} J−H {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-h2}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-k2|}}}|
! style="text-align:left" {{!}} J−K {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-k2}}}
}}
|- style="vertical-align:top"
{{#if:{{{variable2|}}}|
! style="text-align:left" {{!}} [[Variable star|Variable type]]
{{!}} {{{variable2}}}
}}<noinclude>
|}
{{Documentation}}
</noinclude>
bd7d2ca5352dd7b2dc3f58a1ac88cd9daf7194e3
Template:Starbox end
10
157
329
2022-04-04T18:21:34Z
Canopus >Paine Ellsworth
0
add [[WP:RCAT|rcat template]]
wikitext
text/x-wiki
#REDIRECT [[Template:End]]
{{Rcat shell|
{{Wikidata redirect}}
{{R from template shortcut}}
{{R with history}}
}}
ad342c0433bda993d648e9da241703291bbb98a6
Template:Starbox observe
10
159
333
2022-04-04T19:04:21Z
Canopus >Paine Ellsworth
0
per edit request at [[Template talk:Starbox begin#Template-protected edit request on 3 April 2022]] - remove small tags
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude>
|-
! style="text-align: center; background-color: #FFFFC0;" colspan="2" | Observation data<br/>{{#ifeq:{{{epoch}}}|[[J2000.0]] ([[International Celestial Reference System|ICRS]])|[[Epoch (astronomy)|Epoch]] [[J2000.0]] [[Equinox (celestial coordinates)|Equinox]] [[J2000.0]] ([[International Celestial Reference System|ICRS]])| [[Epoch (astronomy)|Epoch]] {{{epoch}}} [[Equinox (celestial coordinates)|Equinox]] {{{equinox|{{{epoch|}}}}}}}}
|- style="vertical-align:top"
! style="text-align:left" | [[Constellation]]
| {{{constell}}}
|- style="vertical-align:top"
{{#if:{{{pronounce<includeonly>|</includeonly>}}}|
! style="text-align:left" {{!}} [[WP:IPA for English|Pronunciation]]
{{!}} {{{pronounce}}}
}}
|- style="vertical-align:top"
! style="text-align:left" | {{nowrap|[[Right ascension]]}}
| {{{ra}}}
|- style="vertical-align:top"
! style="text-align:left" | [[Declination]]
| {{{dec}}}
|- style="vertical-align:top"
{{#if:{{{appmag_v<includeonly>|</includeonly>}}}|
! style="text-align:left" {{!}} {{nowrap|[[Apparent magnitude|Apparent magnitude]] (V)}}
{{!}} {{{appmag_v}}}
}}<noinclude>
|}
{{Documentation}}
</noinclude>
21bf36f2041ff2d017e71e8c048693e9ad9e15db
Template:Starbox reference
10
160
335
2022-05-03T09:40:55Z
Canopus >Primefac
0
update SIMBAD links (TPER)
wikitext
text/x-wiki
<noinclude>
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||Database references}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}<!--
-->{{#if:{{{Simbad<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''[[SIMBAD]]'''</td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad}}} {{{sn|data}}}]</tr>}}<!--
-->{{#if:{{{Simbad2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad2}}} {{{sn2|data2}}}]</tr>}}<!--
-->{{#if:{{{Simbad3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad3}}} {{{sn3|data3}}}]</tr>}}<!--
-->{{#if:{{{Simbad4<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad4}}} {{{sn4|data4}}}]</tr>}}<!--
-->{{#if:{{{Simbad5<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad5}}} {{{sn5|data5}}}]</tr>}}<!--
-->{{#if:{{{Simbad6<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad6}}} {{{sn6|data6}}}]</tr>}}<!--
-->{{#if:{{{Simbad7<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad7}}} {{{sn7|data7}}}]</tr>}}<!--
-->{{#if:{{{Simbad8<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad8}}} {{{sn8|data8}}}]</tr>}}<!--
-->{{#if:{{{Simbad9<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad9}}} {{{sn9|data9}}}]</tr>}}<!--
-->{{#if:{{{NSTED<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''[[Exoplanet Archive]]'''</td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED}}} {{{nn|data}}}]</tr>}}<!--
-->{{#if:{{{NSTED2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED2}}} {{{nn2|data2}}}]</tr>}}<!--
-->{{#if:{{{NSTED3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED3}}} {{{nn3|data3}}}]</tr>}}<!--
-->{{#if:{{{ARICNS<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''ARICNS'''</td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS}}}.htm {{{an|data}}}]</td></tr>}}<!--
-->{{#if:{{{ARICNS2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS2}}}.htm {{{an2|data2}}}]</td></tr>}}<!--
-->{{#if:{{{ARICNS3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS3}}}.htm {{{an3|data3}}}]</td></tr>}}<!--
-->{{#if:{{{EPE<includeonly>|</includeonly>}}}|<tr><td>'''[[Extrasolar Planets Encyclopaedia|Extrasolar Planets<br />Encyclopaedia]]'''</td><td>[https://exoplanet.eu/star.php?st={{{EPE}}} data]</td></tr>}}<!--
-->{{#if:{{{KIC<includeonly>|</includeonly>}}}|<tr><td>'''[[Kepler Input Catalog|KIC]]'''</td><td>[https://archive.stsci.edu/kepler/data_search/search.php?action=Search&ktc_kepler_id={{{KIC}}} data]</td></tr>
}}<noinclude>
|}
{{Documentation}}
</noinclude>
f84999acae32fc7dacb316605220d28af5b2f06d
Module:If empty
828
94
203
2022-05-06T04:38:40Z
Canopus >Dinoguy1000
0
update from sandbox, per [[Template talk:If empty#Backcompat]]
Scribunto
text/plain
local p = {}
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:If empty', removeBlanks = false})
local lastk = 0
for k,v in ipairs(args) do
if v ~= '' then
return v
end
lastk = k
end
end
return p
4bfc0c7c8bf3b63144db1ea12f2260db00421233
Template:Cite Gaia DR2
10
163
341
2022-05-24T21:12:50Z
Canopus >Lithopsian
0
attempt fix for leading space in the source ID (see talk page)
wikitext
text/x-wiki
{{cite journal
| last1=Brown | first1=A. G. A.
| display-authors=etal
| collaboration=Gaia collaboration
| date=August 2018
| title=''Gaia'' Data Release 2: Summary of the contents and survey properties
| journal=[[Astronomy & Astrophysics]]
| volume=616 |at=A1
| arxiv=1804.09365
| bibcode=2018A&A...616A...1G
| bibcode-access=free
| doi=10.1051/0004-6361/201833051
| doi-access=free
| mode={{{mode|}}}
}}{{#if:{{{1|}}}| [http://vizier.u-strasbg.fr/viz-bin/VizieR-S?Gaia%20DR2%20{{Trim|{{{1|}}}}} Gaia DR2 record for this source] at [[VizieR]].}}<noinclude>
{{Documentation}}
</noinclude>
f0d86754ae543ff75617b1a118b720534de42335
Module:Portal
828
64
143
2022-06-05T03:15:40Z
Canopus >Hike395
0
extend image function to take border argument
Scribunto
text/plain
--[==[ This module is a Lua implementation of the old {{Portal}} template. As of February 2019 it is used on nearly 7,900,000 articles.
-- Please take care when updating it! It outputs two functions: p.portal, which generates a list of portals, and p.image, which
-- produces the image name for an individual portal.
-- The portal image data is kept in submodules of [[Module:Portal/images]], listed below:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
--
-- The images data pages are separated by the first letter to reduce server load when images are added, changed, or removed.
-- Previously all the images were on one data page at [[Module:Portal/images]], but this had the disadvantage that all
-- 5,000,000 pages using this module needed to be refreshed every time an image was added or removed.
]==]
local p = {}
-- determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''
local function sandboxVersion(s)
return isSandbox and s..'-sand' or s
end
local templatestyles = 'Module:Portal'..sandbox..'/styles.css'
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
-- List of non-talk namespaces which should not be tracked (Talk pages are never tracked)
local badNamespaces = {'user','template','draft','wikipedia'}
-- Check whether to do tracking in this namespace
-- Returns true unless the page is one of the banned namespaces
local function checkTracking(title)
local thisPage = title or mw.title.getCurrentTitle()
if thisPage.isTalkPage then
return false
end
local ns = thisPage.nsText:lower()
for _, v in ipairs(badNamespaces) do
if ns == v then
return false
end
end
return true
end
local function matchImagePage(s)
-- Finds the appropriate image subpage given a lower-case
-- portal name plus the first letter of that portal name.
if type(s) ~= 'string' or #s < 1 then return end
local firstLetter = mw.ustring.sub(s, 1, 1)
local imagePage
if mw.ustring.find(firstLetter, '^[a-z]') then
imagePage = 'Module:Portal/images/' .. firstLetter .. sandbox
else
imagePage = 'Module:Portal/images/other' .. sandbox
end
return mw.loadData(imagePage)[s]
end
local function getAlias(s)
-- Gets an alias from the image alias data page.
local aliasData = mw.loadData('Module:Portal/images/aliases'..sandbox)
for portal, aliases in pairs(aliasData) do
for _, alias in ipairs(aliases) do
if alias == s then
return portal
end
end
end
end
local function getImageName(s)
-- Gets the image name for a given string.
local default = 'Portal-puzzle.svg|link=|alt='
if type(s) ~= 'string' or #s < 1 then
return default
end
s = mw.ustring.lower(s)
return matchImagePage(s) or matchImagePage(getAlias(s)) or default
end
-- Function to check argument portals for errors, generate tracking categories if needed
-- Function first checks for too few/many portals provided
-- Then checks the portal list to purge any portals that don't exist
-- Arguments:
-- portals: raw list of portals
-- args.tracking: is tracking requested? (will not track on bad titles or namespaces)
-- args.redlinks: should redlinks be displayed?
-- args.minPortals: minimum number of portal arguments
-- args.maxPortals: maximum number of portal arguments
-- Returns:
-- portals = list of portals, with redlinks purged (if args.redlinks=false)
-- trackingCat = possible tracking category
-- errorMsg = error message
function p._checkPortals(portals, args)
local trackingCat = ''
local errMsg = nil
-- Tracking is on by default.
-- It is disabled if any of the following is true
-- 1/ the parameter "tracking" is set to 'no, 'n', or 'false'
-- 2/ the current page fails the namespace or pagename tests
local trackingEnabled = args.tracking and checkTracking()
args.minPortals = args.minPortals or 1
args.maxPortals = args.maxPortals or -1
-- check for too few portals
if #portals < args.minPortals then
errMsg = 'please specify at least '..args.minPortals..' portal'..(args.minPortals > 1 and 's' or '')
trackingCat = (trackingEnabled and '[[Category:Portal templates with too few portals]]' or '')
return portals, trackingCat, errMsg
end
-- check for too many portals
if args.maxPortals >= 0 and #portals > args.maxPortals then
errMsg = 'too many portals (maximum = '..args.maxPortals..')'
trackingCat = (trackingEnabled and '[[Category:Portal templates with too many portals]]' or '')
return portals, trackingCat, errMsg
end
if not args.redlinks or trackingEnabled then
-- make new list of portals that exist
local existingPortals = {}
for _, portal in ipairs(portals) do
local portalTitle = mw.title.new(portal,"Portal")
-- if portal exists, put it into list
if portalTitle and portalTitle.exists then
table.insert(existingPortals,portal)
-- otherwise set tracking cat
elseif trackingEnabled then
trackingCat = "[[Category:Portal templates with redlinked portals]]"
end
end
-- If redlinks is off, use portal list purged of redlinks
portals = args.redlinks and portals or existingPortals
-- if nothing left after purge, set tracking cat
if #portals == 0 and trackingEnabled then
trackingCat = trackingCat.."[[Category:Pages with empty portal template]]"
end
end
return portals, trackingCat, errMsg
end
function p._portal(portals, args)
-- This function builds the portal box used by the {{portal}} template.
-- Normalize all arguments
if args.redlinks == 'include' then args.redlinks = true end
args.addBreak = args['break']
for key, default in pairs({left=false,tracking=true,nominimum=false,
redlinks=false,addBreak=false,border=true}) do
if args[key] == nil then args[key] = default end
args[key] = yesno(args[key], default)
end
local root = mw.html.create('div')
:attr('role', 'navigation')
:attr('aria-label', 'Portals')
:addClass('noprint plainlist')
:addClass(sandboxVersion('portalbox'))
:addClass(args.border and sandboxVersion('portalborder') or '')
:addClass(args.left and 'tleft' or 'tright')
:css('margin', args.margin or nil)
:newline()
local trackingCat = ''
local errMsg = nil
args.minPortals = args.nominimum and 0 or 1
args.maxPortals = -1
portals, trackingCat, errMsg = p._checkPortals(portals, args)
root:wikitext(trackingCat)
-- if error message, put it in the box and return
if errMsg then
if args.border then -- suppress error message when border=no
local errTag = root:tag('strong')
errTag:addClass('error')
errTag:css('padding','0.2em')
errTag:wikitext('Error: '..errMsg)
end
return tostring(root)
end
-- if no portals (and no error), just return tracking category
if #portals == 0 then
return trackingCat
end
-- Start the list. This corresponds to the start of the wikitext table in the old [[Template:Portal]].
local listroot = root:tag('ul')
:css('width', (tonumber(args.boxsize) or 0) > 0 and (args.boxsize .. 'px') or args.boxsize)
-- Display the portals specified in the positional arguments.
for _, portal in ipairs(portals) do
local image = getImageName(portal)
-- Generate the html for the image and the portal name.
listroot
:newline()
:tag('li')
:tag('span')
:wikitext(string.format('[[File:%s|32x28px|class=noviewer]]', image))
:done()
:tag('span')
:wikitext(string.format('[[Portal:%s|%s%sportal]]', portal, portal, args.addBreak and '<br />' or ' '))
end
return tostring(root)
end
function p._image(portal,nostrip)
-- Wrapper function to allow getImageName() to be accessed through #invoke.
-- backward compatibility: if table passed, take first element
if type(portal) == 'table' then
portal = portal[1]
end
local name = getImageName(portal)
-- If nostrip is yes (or equivalent), then allow all metadata (like image borders) to be returned
local strip = not yesno(nostrip)
return strip and name:match('^(.-)|') or name -- FIXME: use a more elegant way to separate borders etc. from the image name
end
local function getAllImageTables()
-- Returns an array containing all image subpages (minus aliases) as loaded by mw.loadData.
local images = {}
for i, subpage in ipairs{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'other'} do
images[i] = mw.loadData('Module:Portal/images/' .. subpage .. sandbox)
end
return images
end
function p._displayAll(portals, args)
-- This function displays all portals that have portal images. This function is for maintenance purposes and should not be used in
-- articles, for two reasons: 1) there are over 1500 portals with portal images, and 2) the module doesn't record how the portal
-- names are capitalized, so the portal links may be broken.
local lang = mw.language.getContentLanguage()
local count = 1
for _, imageTable in ipairs(getAllImageTables()) do
for portal in pairs(imageTable) do
portals[count] = lang:ucfirst(portal)
count = count + 1
end
end
return p._portal(portals, args)
end
function p._imageDupes()
-- This function searches the image subpages to find duplicate images. If duplicate images exist, it is not necessarily a bad thing,
-- as different portals might just happen to choose the same image. However, this function is helpful in identifying images that
-- should be moved to a portal alias for ease of maintenance.
local exists, dupes = {}, {}
for _, imageTable in ipairs(getAllImageTables()) do
for portal, image in pairs(imageTable) do
if not exists[image] then
exists[image] = portal
else
table.insert(dupes, string.format('The image "[[:File:%s|%s]]" is used for both portals "%s" and "%s".', image, image, exists[image], portal))
end
end
end
if #dupes < 1 then
return 'No duplicate images found.'
else
return 'The following duplicate images were found:\n* ' .. table.concat(dupes, '\n* ')
end
end
local function processPortalArgs(args)
-- This function processes a table of arguments and returns two tables: an array of portal names for processing by ipairs, and a table of
-- the named arguments that specify style options, etc. We need to use ipairs because we want to list all the portals in the order
-- they were passed to the template, but we also want to be able to deal with positional arguments passed explicitly, for example
-- {{portal|2=Politics}}. The behaviour of ipairs is undefined if nil values are present, so we need to make sure they are all removed.
args = type(args) == 'table' and args or {}
local portals = {}
local namedArgs = {}
for k, v in pairs(args) do
if type(k) == 'number' and type(v) == 'string' then -- Make sure we have no non-string portal names.
table.insert(portals, k)
elseif type(k) ~= 'number' then
namedArgs[k] = v
end
end
table.sort(portals)
for i, v in ipairs(portals) do
portals[i] = args[v]
end
return portals, namedArgs
end
-- Entry point for sorting portals from other named arguments
function p._processPortalArgs(args)
return processPortalArgs(args)
end
function p.image(frame)
local origArgs = getArgs(frame)
local portals, args = processPortalArgs(origArgs)
return p._image(portals[1],args.border)
end
local function makeWrapper(funcName)
-- Processes external arguments and sends them to the other functions.
return function (frame)
-- If called via #invoke, use the args passed into the invoking
-- template, or the args passed to #invoke if any exist. Otherwise
-- assume args are being passed directly in from the debug console
-- or from another Lua module.
-- Also: trim whitespace and remove blank arguments
local origArgs = getArgs(frame)
-- create two tables to pass to func: an array of portal names, and a table of named arguments.
local portals, args = processPortalArgs(origArgs)
local results = ''
if funcName == '_portal' or funcName == '_displayAll' then
results = frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles} }
end
return results .. p[funcName](portals, args)
end
end
for _, funcName in ipairs{'portal', 'imageDupes', 'displayAll'} do
p[funcName] = makeWrapper('_' .. funcName)
end
return p
078bc1925b1a76f62f668379257fd789d6d85d4b
Template:Reflist
10
87
189
2022-06-11T17:42:16Z
Canopus >Izno
0
correct my error per [[Template talk:Reflist#liststyle and group]]
wikitext
text/x-wiki
<templatestyles src="Reflist/styles.css" /><div class="reflist <!--
-->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!--
-->{{#switch:{{{liststyle|{{{group|}}}}}}|upper-alpha|upper-roman|lower-alpha|lower-greek|lower-roman=reflist-{{{liststyle|{{{group}}}}}}}} <!--
-->{{#if:{{{1|}}}|{{#iferror:{{#ifexpr: {{{1|1}}} > 1 }}||{{#switch:{{{1|}}}|1=|2=reflist-columns-2|#default=reflist-columns-3}} }}}}" <!-- end class
-->{{#if: {{{1|}}}<!-- start style -->
| {{#iferror: {{#ifexpr: {{{1|1}}} > 1 }} |style="column-width: {{{1}}};"}}
| {{#if: {{{colwidth|}}}|style="column-width: {{{colwidth}}};"}}
}}>
{{#tag:references|{{{refs|}}}|group={{{group|}}}|responsive={{#if:{{{1|}}}{{{colwidth|}}}|0|1}}}}</div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using reflist with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Reflist]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | colwidth | group | liststyle | refs }}<noinclude>
{{Documentation}}
</noinclude>
8c65cc88272db6c0f5cf2b49f84d3e460e60ee5f
Template:Clear
10
89
193
2022-06-13T15:31:11Z
Canopus >Xaosflux
0
Changed protection settings for "[[Template:Clear]]": [[WP:High-risk templates|Highly visible template]]: 3MM+ uses ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>
{{documentation}}
</noinclude>
38bab3e3d7fbd3d6800d46556e60bc6bac494d72
Module:Portal/images/s
828
86
187
2022-06-13T17:21:18Z
Canopus >Nihonjoe
0
typo
Scribunto
text/plain
--[==[ This is the "S" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "S". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be omitted.
]==]
return {
["saarc"] = "SAARC 1717549468.png|link=|alt=icon",
["saarland"] = "Flag of Saarland.svg|border|link=|alt=flag",
["saba"] = "Flag of Saba.svg|border|link=|alt=flag",
["sabah"] = "Flag of Sabah.svg|border|link=|alt=flag",
["sacred christian music"] = "Musical note nicu bucule 01.svg|link=|alt=icon",
["saguenay–lac-saint-jean"] = "Flag of Saguenay-Lac-Saint-Jean.svg|border|link=|alt=flag",
["sailing"] = "Sailing pictogram.svg|link=|alt=",
["saint barthelemy"] = "Flag of Saint Barthelemy (local).svg|border|link=|alt=flag",
["saint helena, ascension and tristan da cunha"] = "Flag of Saint Helena.svg|border|link=|alt=flag",
["saint kitts and nevis"] = "Flag of Saint Kitts and Nevis.svg|border|link=|alt=flag",
["saint lucia"] = "Flag of Saint Lucia.svg|border|link=|alt=flag",
["saint martin"] = "Flag of Saint Martin.png|border|link=|alt=flag",
["saint petersburg"] = "Flag of Saint Petersburg Russia.svg|alt=flag",
["saint pierre and miquelon"] = "Flag of Saint-Pierre and Miquelon.svg|border|link=|alt=flag",
["saint vincent and the grenadines"] = "Flag of Saint Vincent and the Grenadines.svg|border|link=|alt=flag",
["saints"] = "Gloriole blur.svg|link=|alt=",
["salad dressing"] = "Ranch dressing.jpg|link=|alt=",
["salmon"] = "Alaska salmon.jpg|link=|alt=",
["samoa"] = "Flag of Samoa.svg|border|link=|alt=flag",
["san antonio"] = "Coat of arms of San Antonio.svg|link=|alt=arms",
["san diego"] = "San Diego,California,USA. - panoramio (139).jpg|link=|alt=photo",
["san diego county"] = "Seal of San Diego County, California.png|link=|alt=seal",
["san diego–tijuana"] = "San Diego-Tijuana JPLLandsat.jpg|border|link=|alt=flag",
["sandwich"] = "Sandwich (1).jpg|link=|alt=",
["san francisco bay area"] = "SF From Marin Highlands3.jpg|border|link=|alt=",
["san francisco neighborhoods"] = "Columbus and Broadway (8219737166).jpg|link=|alt=",
["san luis potosí"] = "Flag of San Luis Potosi.svg|border|link=|alt=flag",
["san marino"] = "Flag of San Marino.svg|border|link=|alt=flag",
["santa barbara county"] = "Seal of Santa Barbara County, California.png|link=|alt=seal",
["santana"] = "Carlos Santana 2005.jpg|link=|alt=",
["santiago, chile"] = "Flag of Santiago de Chile.svg|alt=flag",
["são tomé and príncipe"] = "Flag of Sao Tome and Principe.svg|border|link=|alt=flag",
["são paulo"] = "Bandeira da cidade de São Paulo.svg|link=|alt=",
["salad"] = "Composed salad.jpg|link=|alt=",
["salads"] = "Composed salad.jpg|link=|alt=",
["salt"] = "Keukenzout (NaCl), onder de microscoop.jpg|link=|alt=",
["santiago"] = "Flag of Santiago de Chile.svg|alt=flag",
["sarajevo"] = "Flag of Sarajevo.svg|alt=flag",
["sarawak"] = "Flag of Sarawak.svg|border|link=|alt=flag",
["sasanian empire"] = "Derafsh Kaviani flag of the late Sassanid Empire.svg|border|link=|alt=flag",
["saskatchewan"] = "Flag of Saskatchewan.svg|border|link=|alt=flag",
["saskatchewan communities and neighbourhoods"] = "Flag-map of Saskatchewan.svg|link=|alt=map",
["saturn"] = "Saturn - April 25 2016 (24102807868).png|link=|alt=",
["saudi arabia"] = "Flag of Saudi Arabia.svg|border|link=|alt=flag",
["sausage"] = "Saucisses.svg|link=|alt=",
["sausages"] = "Saucisses.svg|link=|alt=",
["saxony"] = "Flag of Saxony.svg|border|link=|alt=flag",
["saxony-anhalt"] = "Flag of Saxony-Anhalt (state).svg|border|link=|alt=flag",
["schleswig-holstein"] = "Flag of Schleswig-Holstein (state).svg|border|link=|alt=flag",
["schools"] = "School.svg|link=|alt=icon",
["science"] = "Nuvola apps kalzium.svg|alt=icon",
["science and academia"] = "Rachel Carson w (cropped).jpg|link=|alt=photo",
["science fiction"] = "Sf-userbox.png|alt=icon",
["scientology"] = "Scientology e meter blue.jpg|alt=icon",
["scifi"] = "Sf-userbox.png|alt=icon",
["scotland"] = "Flag of Scotland.svg|border|link=|alt=flag",
["scottish islands"] = "ScottishIsles.jpg|link=|alt=map",
["scouting"] = "WikiProject Scouting fleur-de-lis dark.svg|alt=icon",
["sculpture"] = "Noun Project - Sculpture.svg|alt=",
["seafood"] = "Crab-icon.png|link=|alt=",
["seamounts"] = "Seamount.svg|link=|alt=",
["seattle"] = "SpaceNeedleTopClose.jpg|alt=icon",
["sega"] = "SEGA logo.svg|link=|alt=",
["senegal"] = "Flag of Senegal.svg|border|link=|alt=flag",
["selangor"] = "Flag of Selangor.svg|alt=flag",
["seoul"] = "Seal of Seoul.svg|link=|alt=seal",
["september 11 attacks"] = "Y24-Wtc-september-5.jpg|alt=icon",
["serbia"] = "Flag of Serbia.svg|border|link=|alt=flag",
["serbian cuisine"] = "Ćevapčići.jpg|link=|alt=",
["serer people"] = "Serer Royal War Drum (Jung-Jung). 19th Century. Jung-Jung From The Kingdom of Sine (in modern day Senegal).jpg|alt=icon",
["serer religion"] = "Five Pointed Star Lined.svg|link=|alt=",
["set theory"] = "Venn0001.svg|link=|alt=",
["seton hall university"] = "Shu logo.png|link=|alt=logo",
["seventh-day adventist church"] = "James and Ellen White.jpg|link=|alt=",
["severe weather"] = "Marquette, Kansas EF4 tornado on April 14, 2012.png|link=|alt=icon",
["sexuality"] = "Bisexuality symbol (bold, color).svg|alt=icon",
["sex work"] = "Umbrella-159361.svg|link=|alt=",
["seychelles"] = "Flag of Seychelles.svg|border|link=|alt=flag",
["sf"] = "Dragon-149393.svg|alt=icon",
["sfpeople"] = "Dragon-149393.svg|alt=icon",
["sfpubs"] = "Dragon-149393.svg|alt=icon",
["shakespeare"] = "Shakespeare (oval-cropped).png|link=|alt=",
["shakira"] = "S by shakira logo.png|alt=icon",
["shanghai"] = "Shanghainame.png|link=|alt=",
["shania twain"] = "Shania Twain Portrait.jpg|alt=icon",
["sharjah"] = "Flag of Sharjah.svg|border|link=|alt=flag",
["sharks"] = "Greyreefsharksmall2.jpg|alt=icon",
["shenzhen"] = "Shenzhen in Chinese.png|alt=Shenzhen",
["shia islam"] = "Ghadir logo.png|alt=icon",
["shinto"] = "Shinto torii icon vermillion.svg|link=|alt=",
["shreveport"] = "Shreveport-City-Flag.png|border|link=|alt=flag",
["shreya ghoshal"] = "Shreya at concert.jpg|alt=icon",
["shropshire"] = "Flag of Shropshire.svg|alt=flag|link=",
["siberia"] = "Kuznetsk Alatau 3.jpg|border|link=|alt=",
["sierra leone"] = "Flag of Sierra Leone.svg|border|link=|alt=flag",
["sikhism"] = "Khanda emblem.svg|link=|alt=",
["sikkim"] = "Seal of Sikkim color.png|link=|alt=seal",
["silent film"] = "Video-x-generic.svg|link=|alt=",
["silesia"] = "Silesia Inferior COA.svg|alt=icon",
["sinaloa"] = "Flag of Sinaloa.svg|border|link=|alt=flag",
["sindh"] = "Flag of Sindh.svg|border|link=|alt=flag",
["singapore"] = "Flag of Singapore.svg|border|link=|alt=flag",
["sint eustatius"] = "Flag of Sint Eustatius.svg|border|link=|alt=flag",
["sint maarten"] = "Flag of Sint Maarten.svg|border|link=|alt=flag",
["slavery"] = "IJzeren voetring voor gevangenen transparent background.png|border|link=|alt=icon",
["slipknot"] = "SlipknotProject.png|alt=icon",
["slovak republic"] = "Flag of Slovakia.svg|border|link=|alt=flag",
["slovakia"] = "Flag of Slovakia.svg|border|link=|alt=flag",
["slovenia"] = "Flag of Slovenia.svg|border|link=|alt=flag",
["sm entertainment"] = "SM Entertainment Logo.svg|link=|alt=",
["snakes"] = "Snake icon.svg|link=|alt=",
["snk"] = "SNK Playmore logo and wordmark.png|link=|alt=",
["snooker"] = "Snooker balls triangled.png|alt=icon",
["soap operas and telenovelas"] = "Drama-icon.svg|alt=icon",
["soccer in the united states"] = "Soccerball USA.png|link=|alt=",
["social and political philosophy"] = "P derecho.svg|link=|alt=",
["social movements"] = "Peace sign.svg|link=|alt=",
["social science"] = "P social sciences-lightblue.png|link=|alt=icon",
["social sciences"] = "DrustveneNauke.png|alt=icon",
["social welfare and social work"] = "Vista Login Manager Cropped.svg|alt=icon",
["socialism"] = "Red flag II.svg|alt=icon",
["society"] = "Social sciences.svg|alt=icon",
["sociology"] = "Logo sociology.svg|link=|alt=",
["soft drinks"] = "Soft Drink.svg|link=|alt=",
["software"] = "Crystal Clear device cdrom unmount.png|alt=icon",
["software testing"] = "Green bug and broom.svg|alt=icon",
["solar system"] = "Solar system.jpg|link=|alt=",
["solomon islands"] = "Flag of Solomon Islands.svg|border|link=|alt=flag",
["somalia"] = "Flag of Somalia.svg|border|link=|alt=flag",
["somaliland"] = "Flag of Somaliland.svg|border|link=|alt=flag",
["somerset"] = "Somerset shield.png|alt=icon",
["sonic"] = "Chaos emeralds.svg|alt=icon",
["sonora"] = "Flag of Sonora.svg|border|link=|alt=flag",
["sony"] = "Sony logo.svg|link=|alt=",
["sony playstation"] = "PS3-slim-console.png|link=|alt=",
["soup"] = "Shrimp and corn chowder.jpg|link=|alt=",
["soups"] = "Shrimp and corn chowder.jpg|link=|alt=",
["south africa"] = "Flag of South Africa.svg|border|link=|alt=flag",
["south america"] = "South America (orthographic projection).svg|link=|alt=map",
["south asia"] = "India 78.40398E 20.74980N.jpg|link=|alt=",
["south australia"] = "Flag of South Australia.svg|border|link=|alt=flag",
["south carolina"] = "Flag of South Carolina.svg|border|link=|alt=flag",
["south dakota"] = "Flag of South Dakota.svg|border|link=|alt=flag",
["south east england"] = "EnglandSouthEast.png|alt=icon",
["south georgia and the south sandwich islands"] = "Flag of South Georgia and the South Sandwich Islands.svg|border|link=|alt=flag",
["south korea"] = "Flag of South Korea.svg|border|link=|alt=flag",
["south park"] = "South Park sign logo.png|link=|alt=",
["south sudan"] = "Flag of South Sudan.svg|border|link=|alt=flag",
["southeast asia"] = "Location Southeast Asia.svg|link=|alt=",
["southern california"] = "USA California Southern location map.svg|link=|alt=map",
["southwest asia"] = "Southwest-Asia-map.PNG|link=|alt=",
["soviet union"] = "Flag of the Soviet Union.svg|border|link=|alt=flag",
["soy"] = "CSIRO ScienceImage 3273 Soybeans.jpg|link=|alt=",
["space"] = "Earth-moon.jpg|link=|alt=",
["spaceflight"] = "RocketSunIcon.svg|link=|alt=",
["spain"] = "Flag of Spain.svg|border|link=|alt=flag",
["spanish american wars of independence"] = "Red versus blue swords.svg|alt=icon",
["special operations"] = "APP-6 Special Operations Forces.svg|link=|alt=",
["speculative fiction"] = "Dragon-149393.svg|alt=icon",
["speculative fiction/fantasy"] = "Masked man.svg|link=|alt=icon",
["speculative fiction/horror"] = "Vampire Smiley.png|alt=icon",
["speculative fiction/people"] = "Dragon-149393.svg|alt=icon",
["speculative fiction/publications"] = "Dragon-149393.svg|alt=icon",
["spices"] = "Thymus vulgaris.jpg|link=|alt=icon",
["spirituality"] = "EndlessKnot03d.png|link=|alt=",
["spongebob squarepants"] = "WikiProject SpongeBob logo - Logo.svg|alt=icon",
["sports"] = "Sports icon.png|link=|alt=",
["sports and games"] = "Sports and games.png|alt=icon",
["sports in canada"] = "Flag shirt of Canada.png|alt=icon",
["sport of athletics"] = "Roman bronze copy of Myron’s Discobolos, 2nd century CE (Glyptothek Munich).jpg|link=|alt=",
["sri lanka"] = "Flag of Sri Lanka.svg|border|link=|alt=flag",
["sri lankan cuisine"] = "Kiribath (milk rice).jpg|link=|alt=",
["st. john's, newfoundland and labrador"] = "City of St. John's.jpg|link=|alt=",
["st. louis"] = "Flag of St. Louis, Missouri.svg|border|link=|alt=flag",
["staffordshire"] = "Staffordshire Flag.svg|border|link=|alt=flag",
["stamford"] = "Stamford town crest.png|link=|alt=crest",
["stanford university"] = "Stanford logo.png|link=|alt=logo",
["star"] = "He1523a.jpg|alt=icon",
["stars"] = "He1523a.jpg|alt=icon",
["star trek"] = "Delta-shield.svg|link=|alt=",
["star wars"] = "Lightsaber blue.svg|link=|alt=",
["state of georgia"] = "Flag of Georgia (U.S. state).svg|border|link=|alt=flag",
["state of mexico"] = "Flag of Mexico (state).png|border|link=|alt=flag",
["state university of new york"] = "SUNY brandmark.svg|link=|alt=brandmark",
["state university system of florida"] = "SUSF Locations.jpg|link=|alt=map",
["statistics"] = "Fisher iris versicolor sepalwidth.svg|alt=icon",
["statue of liberty"] = "FREEDOM FOR ALL!.jpg|alt=",
["steampunk"] = "Steampunk-falksen.jpg|alt=icon",
["stockholm"] = "Flag of Stockholm.svg|alt=flag",
["strategy games"] = "Chess.svg|alt=icon",
["strawberries"] = "FraiseFruitPhoto.jpg|link=|alt=",
["strawberry"] = "FraiseFruitPhoto.jpg|link=|alt=",
["street food"] = "Food Truck - The Noun Project.svg|link=|alt=",
["street foods"] = "Food Truck - The Noun Project.svg|link=|alt=",
["submarine"] = "Submarine.svg|alt=icon",
["submarines"] = "Submarine.svg|alt=icon",
["sudan"] = "Flag of Sudan.svg|border|link=|alt=flag",
["sufism"] = "Soefi symbool.gif|link=|alt=",
["super bowl"] = "Lombardi Trophy.png|link=|alt=",
["superfunds"] = "Superfund sites.svg|link=|alt=map",
["superhero fiction"] = "Question bubble thing.svg|link=|alt=",
["supermarket"] = "ShoppingCart.svg|link=|alt=",
["supermarkets"] = "ShoppingCart.svg|link=|alt=",
["supreme court of the united states"] = "Supreme Court.jpg|link=|alt=",
["surat"] = "Surat at night.JPG|link=|alt=photo",
["surfing"] = "Pictograms-nps-water-surfing.svg|link=|alt=",
["suriname"] = "Flag of Suriname.svg|border|link=|alt=flag",
["surrey"] = "EnglandSurrey.png|alt=icon",
["sushi"] = "Emojione 1F363.svg|border|link=|alt=",
["sustainability"] = "Nested sustainability-v2.svg|border|link=|alt=",
["sussex"] = "SussexBrit5.PNG|link=|alt=",
["sustainable development"] = "Sustainable development.svg|alt=icon",
["sweden"] = "Flag of Sweden.svg|border|link=|alt=flag",
["swimming"] = "Swimming pictogram.svg|link=|alt=",
["switzerland"] = "Flag of Switzerland.svg|border|link=|alt=flag",
["sydney"] = "Sydney COA.gif|alt=icon",
["syracuse, new york"] = "SyracuseSkyline01.JPG|link=|alt=",
["syria"] = "Flag of Syria.svg|border|link=|alt=flag",
["syriac christianity"] = "Bible and Pulpit, Mor Hananyo.jpg|alt=icon",
["syriac"] = "Syriac Sertâ book script.jpg|link=|alt=",
["syrian civil war"] = "Flag of Syria (2011 combined).svg|border|link=|alt=flag",
["systems"] = "Complex-adaptive-system.jpg|link=|alt=diagram",
["systems engineering initiative"] = "Systems Engineering Process II.gif|link=|alt=diagram",
["systems science"] = "Complex-adaptive-system.jpg|link=|alt=diagram"
}
a240880fd11e77e94cd6091361c41c9fdf8e85df
Template:Starbox detail
10
156
327
2022-06-15T13:02:40Z
Canopus >Primefac
0
tweak to avoid false positives
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||Details{{{source|}}}}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}</th></tr><!--
--><tr><th colspan="2" style="text-align: center">{{{component1<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{mass<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass}}} {{Solar mass|link=yes}}</td></tr>}}<!--
-->{{#if:{{{mass_mj<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass_mj}}} [[Jupiter mass|''M''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius}}} {{Solar radius|link=yes}}</td></tr>}}<!--
-->{{#if:{{{radius_rj<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_rj}}} [[Jupiter radius|''R''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius_km<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_km}}} [[kilometer|km]]</td></tr>}}<!--
-->{{#if:{{{luminosity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Luminosity]]'''</td><td>{{{luminosity}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_bolometric<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (bolometric)'''</td><td>{{{luminosity_bolometric}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_visual<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (visual, L<sub>V</sub>)'''</td><td>{{{luminosity_visual}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{habitable_inner<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] inner limit'''</td><td>{{{habitable_inner}}}</td></tr>}}<!--
-->{{#if:{{{habitable_outer<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] outer limit'''</td><td>{{{habitable_outer}}}</td></tr>}}<!--
-->{{#if:{{{gravity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Surface gravity]] (log ''g'')'''</td><td>{{{gravity}}} [[Centimetre–gram–second system of units|cgs]]</td></tr>}}<!--
-->{{#if:{{{temperature<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Effective temperature|Temperature]]'''</td><td>{{{temperature}}} [[Kelvin|K]]</td></tr>}}<!--
-->{{#if:{{{metal<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]'''</td><td>{{{metal}}}</td></tr>}}<!--
-->{{#if:{{{metal_fe<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]''' [Fe/H]</td><td>{{{metal_fe}}} [[Decimal exponent|dex]]</td></tr>}}<!--
-->{{#if:{{{rotation<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar rotation|Rotation]]'''</td><td>{{{rotation}}}</td></tr>}}<!--
-->{{#if:{{{rotational_velocity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Projected rotational velocity|Rotational velocity]] (''v'' sin ''i'')'''</td><td>{{{rotational_velocity}}} km/s</td></tr>}}<!--
-->{{#if:{{{age<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar evolution|Age]]'''</td><td>{{{age}}} years</td></tr>}}<!--
-->{{#if:{{{age_myr<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age|}}}| |'''[[Stellar evolution|Age]]'''}}</td><td>{{{age_myr}}} [[megayear|Myr]]</td></tr>}}<!--
-->{{#if:{{{age_gyr<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age|}}}| |'''[[Stellar evolution|Age]]'''}}</td><td>{{{age_gyr}}} [[gigayear|Gyr]]</td></tr>}}<!--
--><tr><th colspan="2" style="text-align: center">{{{component2<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{mass2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass2}}} {{Solar mass|link=yes}}</td></tr>}}<!--
-->{{#if:{{{mass_mj2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass_mj2}}} [[Jupiter mass|''M''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius2}}} {{Solar radius|link=yes}}</td></tr>}}<!--
-->{{#if:{{{radius_rj2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_rj2}}} [[Jupiter radius|''R''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius_km2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_km2}}} [[kilometer|km]]</td></tr>}}<!--
-->{{#if:{{{luminosity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity'''</td><td>{{{luminosity2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_bolometric2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (bolometric)'''</td><td>{{{luminosity_bolometric2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_visual2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (visual, L<sub>V</sub>)'''</td><td>{{{luminosity_visual2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{habitable_inner2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] inner limit'''</td><td>{{{habitable_inner2}}}</td></tr>}}<!--
-->{{#if:{{{habitable_outer2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] outer limit'''</td><td>{{{habitable_outer2}}}</td></tr>}}<!--
-->{{#if:{{{gravity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Surface gravity]] (log ''g'')'''</td><td>{{{gravity2}}} [[Centimetre–gram–second system of units|cgs]]</td></tr>}}<!--
-->{{#if:{{{temperature2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Effective temperature|Temperature]]'''</td><td>{{{temperature2}}} [[Kelvin|K]]</td></tr>}}<!--
-->{{#if:{{{metal2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]'''</td><td>{{{metal2}}}</td></tr>}}<!--
-->{{#if:{{if empty|{{{metal_fe2|}}}|{{{metal2_fe|}}}|<noinclude>x</noinclude>}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]''' [Fe/H]</td><td>{{{metal2_fe|{{{metal_fe2}}}}}} [[Decimal exponent|dex]]</td></tr>}}<!--
-->{{#if:{{{rotation2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar rotation|Rotation]]'''</td><td>{{{rotation2}}}</td></tr>}}<!--
-->{{#if:{{{rotational_velocity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Projected rotational velocity|Rotational velocity]] (''v'' sin ''i'')'''</td><td>{{{rotational_velocity2}}} km/s</td></tr>}}<!--
-->{{#if:{{{age2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Star#Age_and_size_of_stars|Age]]'''</td><td>{{{age2}}} years</td></tr>}}<!--
-->{{#if:{{{age_myr2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age2|}}}| |'''[[Star#Age_and_size_of_stars|Age]]'''}}</td><td>{{{age_myr2}}} [[megayear|Myr]]</td></tr>}}<!--
-->{{#if:{{{age_gyr2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age2|}}}| |'''[[Star#Age_and_size_of_stars|Age]]'''}}</td><td>{{{age_gyr2}}} [[gigayear|Gyr]]</td></tr>}}<noinclude>
|}
<!-- Please add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
{{Documentation}}
</noinclude>
7f2d91f20c11e77a3a015d033ec4771978d97588
Template:Carina (constellation)
10
161
337
2022-06-15T14:50:36Z
Canopus >RL0919
0
Removing link(s) [[Wikipedia:Articles for deletion/LEDA 2791735]] closed as delete ([[WP:XFDC#4.0.13|XFDcloser]])
wikitext
text/x-wiki
{{Navbox
| name = Carina (constellation)
| title = [[Carina (constellation)|Carina constellation]]
| bodyclass = hlist
| state = {{{state|<noinclude>uncollapsed</noinclude>}}}
| group1 = [[Star]]s<br>([[List of stars in Carina|list]])
| list1 =
{{Navbox|subgroup
| group1 = [[Bayer designation|Bayer]]
| list1 =
* [[Canopus|α (Canopus)]]
* [[Beta Carinae|β (Miaplacidus)]]
* [[Epsilon Carinae|ε (Avior)]]
* [[Eta Carinae|η]]
* [[Theta Carinae|θ]]
* [[Iota Carinae|ι (Aspidiske)]]
* [[Upsilon Carinae|υ]]
* [[Chi Carinae|χ]]
* [[Omega Carinae|ω]]
| group3 = [[Variable star designation|Variable]]
| list3 =
* [[R Carinae|R]]
* [[HD 88366|S]]
* [[T Carinae|T (not variable)]]
* [[HD 95109|U]]
* [[V Carinae|V]]
* [[X Carinae|X]]
* [[Y Carinae|Y]]
* [[RT Carinae|RT]]
* [[UX Carinae|UX]]
* [[VY Carinae|VY]]
* [[WZ Carinae|WZ]]
* [[XY Carinae|XY]]
* [[XZ Carinae|XZ]]
* [[YZ Carinae|YZ]]
* [[AG Carinae|AG]]
* [[BO Carinae|BO]]
* [[CK Carinae|CK]]
* [[CR Carinae|CR]]
* [[DW Carinae|DW]]
* [[EM Carinae|EM]]
* [[EY Carinae|EY]]
* [[GG Carinae|GG]]
* [[GH Carinae|GH]]
* [[GL Carinae|GL]]
* [[GZ Carinae|GZ]]
* [[HH Carinae|HH]]
* [[HR Carinae|HR]]
* [[IW Carinae|IW]]
* [[IX Carinae|IX]]
* [[OY Carinae|OY]]
* [[PP Carinae|PP (p)]]
* [[QU Carinae|QU]]
* [[QX Carinae|QX]]
* [[HD 88661|QY]]
* [[QZ Carinae|QZ]]
* [[V337 Carinae|V337 (q)]]
* [[HD 65750|V341]]
* [[V343 Carinae|V343 (d)]]
* [[V344 Carinae|V344 (f)]]
* [[V345 Carinae|V345 (E)]]
* [[V348 Carinae|V348]]
* [[V357 Carinae|V357 (a)]]
* [[HD 92664|V364]]
* [[V368 Carinae|V368]]
* [[HD 91619|V369]]
* [[HD 92207|V370]]
* [[HD 96919|V371 (z<sup>2</sup>)]]
* [[V372 Carinae|V372]]
* [[HD 66194|V374]]
* [[V375 Carinae|V375]]
* [[V376 Carinae|V376 (b<sup>1</sup>)]]
* [[HD 92024|V381]]
* [[V382 Carinae|V382 (x)]]
* [[V386 Carinae|V386]]
* [[V390 Carinae|V390]]
* [[V392 Carinae|V392]]
* [[HD 90657|V398]]
* [[V399 Carinae|V399 (P)]]
* [[V403 Carinae|V403]]
* [[HD 60435|V409]]
* [[HD 96248|V414]]
* [[HR 2554|V415 (A)]]
* [[HD 94546|V428]]
* [[HD 96446|V430]]
* [[HD 97152|V431]]
* [[V448 Carinae|V448 (O)]]
* [[V450 Carinae|V450]]
* [[HR 3153|V460]]
* [[V461 Carinae|V461]]
* [[V469 Carinae|V469]]
* [[V473 Carinae|V473]]
* [[V478 Carinae|V478]]
* [[V482 Carinae|V482]]
* [[V486 Carinae|V486]]
* [[V487 Carinae|V487]]
* [[V492 Carinae|V492]]
* [[V495 Carinae|V495]]
* [[V507 Carinae|V507]]
* [[V514 Carinae|V514]]
* [[V518 Carinae|V518]]
* [[HD 92964|V519]]
* [[V520 Carinae|V520 (w)]]
* [[V522 Carinae|V522]]
* [[V524 Carinae|V524]]
* [[V528 Carinae|V528]]
* [[V532 Carinae|V532]]
* [[V533 Carinae|V533 (y)]]
* [[V535 Carinae|V535]]
* [[HD 307938|V557]]
* [[HD 93205|V560]]
* [[HD 85567|V596]]
* [[HD 87643|V640]]
* [[V655 Carinae|V655]]
* [[V906 Carinae|V906]]
| group4 = [[Bright Star Catalogue|HR]]
| list4 =
* [[HD 44267|2278]]
* [[HD 46569|2400]]
* [[HD 47001|2416]]
* [[N Carinae|2435 (N)]]
* [[HD 49517|2515]]
* [[HD 49689|2523]]
* [[HD 49705|2524]]
* [[HD 51210|2592]]
* [[HD 52603|2634]]
* [[HD 52622|2638]]
* [[HD 53047|2652]]
* [[HD 53349|2661]]
* [[HD 54732|2698]]
* [[HD 56239|2754]]
* [[HD 56705|2767]]
* [[HD 57852|2813]]
* [[HD 57917|2815]]
* [[HD 59219|2862]]
* [[HD 60060|2884]]
* [[HD 60228|2892]]
* [[HD 61031|2925]]
* [[HD 61248|2934 (Q)]]
* [[HD 61394|2941]]
* [[HD 62758|3006]]
* [[HD 62897|3012]]
* [[HD 63382|3031]]
* [[HD 63926|3056]]
* [[HD 64067|3062]]
* [[HD 64185|3070]]
* [[HD 65189|3100]]
* [[HD 65273|3105]]
* [[HD 65662|3120]]
* [[HD 65867|3133]]
* [[HD 65907|3138]]
* [[HD 65908|3139]]
* [[HD 66341|3152]]
* [[HD 66441|3156]]
* [[HR 3159|3159 (D)]]
* [[HD 66607|3161]]
* [[HD 67364|3180]]
* [[HD 68423|3217]]
* [[HD 68434|3218]]
* [[HR 3220|3220 (B)]]
* [[HD 69863|3260 (C)]]
* [[HD 70267|3274]]
* [[HD 70839|3293]]
* [[HD 70982|3298]]
* [[HD 72322|3368]]
* [[HD 73389|3414 (e<sup>2</sup>)]]
* [[HD 73390|3415 (e<sup>1</sup>)]]
* [[HD 73887|3432]]
* [[HD 74148|3443]]
* [[HD 74341|3455]]
* [[HD 74622|3471]]
* [[HD 75086|3489]]
* [[HD 76113|3536]]
* [[HD 76346|3549]]
* [[HD 76538|3560]]
* [[HD 76728|3571 (c)]]
* [[HD 77370|3598 (b<sup>2</sup>)]]
* [[HD 77615|3604]]
* [[HD 78293|3622]]
* [[HD 78632|3632]]
* [[HR 3643|3643 (G)]]
* [[HD 79447|3663 (i)]]
* [[HD 79698|3673]]
* [[HD 80094|3691]]
* [[HD 80126|3693]]
* [[HD 80230|3696 (g)]]
* [[HD 80671|3712]]
* [[HD 80951|3720]]
* [[HD 80950|3721]]
* [[HD 81101|3728 (k)]]
* [[HD 81502|3740]]
* [[HD 81613|3742]]
* [[HD 81830|3752]]
* [[HD 82068|3761]]
* [[HD 82347|3776]]
* [[HD 82350|3777]]
* [[HD 82406|3783]]
* [[HD 82858|3813]]
* [[HD 83095|3821 (H)]]
* [[HD 83183|3825 (h)]]
* [[HD 83944|3856 (m)]]
* [[HD 84121|3863]]
* [[HD 84152|3864]]
* [[HD 84810|3884 (l)]]
* [[HD 84850|3887]]
* [[HD 85655|3913]]
* [[HD 85656|3914]]
* [[HD 86606|3944]]
* [[HD 87238|3957]]
* [[HD 87283|3960]]
* [[HD 87436|3966]]
* [[HD 87438|3967]]
* [[HD 87543|3971]]
* [[HD 88323|3995]]
* [[HD 88473|4002]]
* [[HD 88825|4018]]
* [[HD 88907|4022]]
* [[HD 88981|4025 (M)]]
* [[HD 89263|4043]]
* [[HD 89715|4065]]
* [[HD 90264|4089 (L)]]
* [[HD 90289|4091]]
* [[HD 90454|4095]]
* [[HR 4102|4102 (I)]]
* [[HD 90630|4105]]
* [[HD 90853|4114 (s)]]
* [[HD 90874|4115]]
* [[HD 91056|4120]]
* [[HD 91270|4128]]
* [[HR 4138|4138 (K)]]
* [[HD 91496|4142]]
* [[HD 91533|4144]]
* [[HD 91767|4151]]
* [[HD 91942|4159 (r)]]
* [[HD 92063|4164 (t<sup>1</sup>)]]
* [[HD 92397|4177 (t<sup>2</sup>)]]
* [[HD 92436|4179]]
* [[HD 92682|4186]]
* [[HD 93163|4204]]
* [[HD 93194|4205]]
* [[HD 93344|4211]]
* [[HD 93359|4212]]
* [[HD 93372|V213]]
* [[HD 93502|4217]]
* [[HD 93540|4219]]
* [[HD 93549|4220]]
* [[HD 93607|4222]]
* [[HD 93662|4226]]
* [[HD 93943|4239]]
* [[HD 94510|4257 (u)]]
* [[HD 94650|4262]] <!--Search the HR number on SIMBAD for this star-->
* [[HD 94683|4266]]
* [[HD 95208|4279]]
* [[HD 95324|4290]]
* [[HD 96544|4323]]
* [[HD 96566|4325 (z<sup>1</sup>)]]
* [[HD 96568|4326]]
* [[HD 96706|4329]]
* [[HD 97472|4349]]
* [[HD 97583|4355]]
* [[HD 97670|4361]]
* [[HD 98560|4384]]
| group5 = [[Henry Draper Catalogue|HD]]
| list5 =
* [[HD 49219|49219]]
* [[HD 51608|51608]]
* [[HD 53143|53143]]
* [[HD 54967|54967]]
* [[HD 63765|63765]]
* [[HD 65216|65216]]
* [[HD 79699|79699]]
* [[HD 81896|81896]]
* [[HD 82458|82458]]
* [[HD 84046|84046]]
* [[HD 89805|89805]]
* [[HD 90074|90074]]
* [[HD 90657|90657]]
* [[HD 91094|91094]]
* [[HD 92399|92399]]
* [[HD 92536|92536]]
* [[HD 93129A|93129A]]
* [[HD 93250|93250]]
* [[HD 93403|93403]]
* [[HD 93645|93645]]
* [[HD 93695|93695]]
* [[HD 93738|93738]]
* [[HD 93739|93739]]
* [[HD 93843|93843]]
* [[HD 94275|94275]]
* [[HD 94305|94305]]
* [[HD 94491|94491]]
* [[HD 95086|95086]]
* [[HD 95122|95122]]
* [[HD 96088|96088]]
* [[HD 97950|97950]]
* [[HD 98025|98025]]
| group6 = [[Gliese catalogue|Gliese]]
| list6 =
| group7 = Other
| list7 =
* [[BPM 6502]]
* [[CPD−57° 2874]]
* [[CPD−59° 2628]]
* [[CPD−59° 2635]]
* [[DENIS J081730.0−615520|DEN 0817−6155]]
* [[AXP 1E 1048-59|1E 1048-59]]
* [[FO 15]]
* [[He 2-38]]
* [[Innes' star]]
* [[LHS 288]]
* [[NGC 3603-A1]]
* [[NGC 3603-B]]
* [[NGC 3603-C]]
* [[OGLE-TR-111]]
* [[OGLE-TR-113]]
* [[OGLE-TR-122]]
* [[OGLE-TR-123]]
* [[OGLE-TR-132]]
* [[OGLE-TR-182]]
* [[OGLE-TR-211]]
* [[OGLE2-TR-L9]]
* [[PSR J1048-5832]]
* [[PSR J1119-6127]]
* [[2S 0921-630]]
* [[Sher 25]]
* [[SS73 17]]
* [[Tr 16-104]]
* [[WR 16]]
* [[WR 18]]
* [[WR 20a]]
* [[WR 21a]]
* [[WR 22]]
* [[WR 23]]
* [[WR 24]]
* [[WR 25]]
* [[WR 30]]
* [[WR 30a]]
* [[WR 31a]]
* [[WR 40]]
* [[WR 42e]]
* [[AWI0005x3s]]
* [[WRA 751]] <!--Simbad ID is V432 Car-->
}}
|group2 = [[Star cluster|Star<br/>clusters]]
|list2 =
{{Navbox|subgroup
|group1=[[Stellar association|Association]]
|list1=
* [[Carina OB1]]
* [[Carina OB2]]
|group2=[[Open cluster|Open]]
|list2=
* [[Collinder 228]]
* [[IC 2602]]
* [[IC 2714]]
* [[NGC 2516]]
* [[NGC 2609]]
* [[NGC 3036]]
* [[NGC 3114]]
* [[NGC 3247]]
* [[NGC 3255]]
* [[NGC 3293]]
* [[NGC 3324]]
* [[NGC 3496]]
* [[NGC 3519]]
* [[NGC 3532]]
* [[NGC 3572]]
* [[NGC 3590]]
* [[NGC 3603]]
* [[Trumpler 14]]
* [[Trumpler 15]]
* [[Trumpler 16]]
* [[Westerlund 2]]
|group3=[[Globular cluster|Globular]]
|list3=
* [[NGC 2808]]
}}
|group3 = [[Nebula]]e
|list3=
{{Navbox|subgroup
|group1=[[H II region|H II]]
|list1=
* [[Carina Nebula]]
* [[NGC 3199]]
* [[NGC 3576]]
* [[NGC 3579]]
* [[NGC 3581]]
* [[NGC 3582]]
* [[NGC 3584]]
* [[NGC 3586]]
* [[RCW 49]]
|group2=[[Reflection nebula|Reflection]]
|list2=
* [[Homunculus Nebula]]
* [[IC 2220]]
* [[NGC 3503]]
|group3=[[Planetary nebula|Planetary]]
|list3=
* [[He 2-36]]
* [[Hen 2-47]]
* [[IC 2448]]
* [[IC 2501]]
* [[IC 2553]]
* [[NGC 2867]]
* [[NGC 3211]]
|group4=[[Supernova remnant|SNR]]
|list4=
* [[G290.1-0.8]]
|group5=[[Pulsar wind nebula|Pulsar wind]]
|list5=
* [[IGR J11014−6103]]
}}
|group4 = [[Galaxy|Galaxies]]
|list4=
{{Navbox|subgroup
|group1=[[Messier object|Messier]]
|list1=
|group2=[[New General Catalogue|NGC]]
|list2=
* [[NGC 2191|2191]]
* [[NGC 2369|2369]]
* [[NGC 2369A|2369A]]
* [[NGC 2369B|2369B]]
* [[NGC 2381|2381]]
* [[NGC 2417|2417]]
* [[NGC 2502|2502]]
* [[NGC 2640|2640]]
* [[NGC 2714|2714]]
* [[NGC 2788|2788]]
* [[NGC 2822|2822]]
* [[NGC 2836|2836]]
* [[NGC 2842|2842]]
* [[NGC 2887|2887]]
* [[NGC 3059|3059]]
* [[NGC 3136|3136]]
* [[NGC 3136A|3136A]]
* [[NGC 3136B|3136B]]
|group3=Other
|list3=
* [[Carina Dwarf Spheroidal Galaxy]]
}}
|group5=[[Galaxy cluster|Galaxy<br/>clusters]]
|list5=
* [[Abell 3391]]
* [[Abell 3395]]
* [[Bullet Cluster]]
|group6=Other
|list6=
* [[GRB 000131]]
* [[GRB 080916C]]
}}<noinclude>
== Documentation ==
{{Universe navboxes}}
[[Category:Stars of constellation templates|Carina]]
</noinclude>
b3e9a604f6e67f2ecee2dbda375f4d9ba3b2bc17
Template:Starbox image
10
158
331
2022-06-16T17:59:55Z
Canopus >MusikBot II
0
Changed protection settings for "[[Template:Starbox image]]": [[Wikipedia:High-risk templates|High-risk template or module]]: 2501 transclusions ([[User:MusikBot II/TemplateProtector|more info]]) ([Edit=Require extended confirmed access] (indefinite) [Move=Require administrator access] (indefinite))
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><td colspan="2" style="text-align:center;"><div style="text-align: center; margin-left:auto; margin-right:auto">{{{image}}}{{#ifeq:{{#invoke:String|sub|{{{image}}}|1|4}}|<div||<br/>}}{{{caption}}}{{#if:{{{credit|}}}|<br>'''Credit''': ''{{{credit}}}''}}</div></tr></td><noinclude>
|}
{{Documentation}}
</noinclude>
791822619c27809b308010e9b9fb71720d2f98f0
Module:Portal bar/styles.css
828
119
253
2022-06-17T04:36:59Z
Canopus >Hike395
0
update styles to implement related portals
text
text/plain
/* {{pp|small=y}} */
.portal-bar {
font-size: 88%;
font-weight: bold;
display:flex;
justify-content: center;
align-items: baseline;
}
.portal-bar-bordered {
padding: 0 2em;
background-color: #fdfdfd;
border: 1px solid #a2a9b1;
clear: both;
margin: 1em auto 0;
}
.portal-bar-related {
font-size: 100%;
justify-content: flex-start;
}
.portal-bar-unbordered {
padding: 0 1.7em;
margin-left: 0;
}
.portal-bar-header {
margin: 0 1em 0 0.5em;
flex: 0 0 auto;
min-height: 24px;
}
.portal-bar-content {
display:flex;
flex-flow: row wrap;
flex:0 1 auto;
padding: 0.15em 0;
column-gap: 1em;
align-items: baseline;
}
.portal-bar-content-related {
}
.portal-bar-item {
display:inline-block;
margin:0.15em 0.2em;
min-height:24px;
line-height:24px;
}
@media screen and (max-width:768px) {
.portal-bar {
font-size: 88%;
font-weight: bold;
display:flex;
flex-flow: column wrap;
align-items: baseline;
}
.portal-bar-header {
text-align: center;
flex:0;
padding-left: 0.5em;
margin: 0 auto;
}
.portal-bar-related {
font-size: 100%;
align-items: flex-start;
}
.portal-bar-content {
display:flex;
flex-flow: row wrap;
align-items: center;
flex:0;
column-gap: 1em;
border-top: 1px solid #a2a9b1;
margin: 0 auto;
}
.portal-bar-content-related {
border-top: none;
margin: 0;
}
}
/* .navbox + .portal-bar-bordered */
.navbox + link + .portal-bar-bordered {
margin-top: -1px;
}
.navbox + style + .portal-bar-bordered {
margin-top: -1px;
}
.portal-bar + .navbox-styles + .navbox{
margin-top: -1px;
}
ec6e77726e7d76d00d66cefce85c3e7d2006d3c5
Module:Portal bar
828
118
251
2022-06-17T04:37:48Z
Canopus >Hike395
0
implement related portals with larger icons
Scribunto
text/plain
-- This module implements {{portal bar}}.
require('Module:No globals')
-- determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''
local portalModule = require('Module:Portal'..sandbox)
local getImageName = portalModule._image
local checkPortals = portalModule._checkPortals
local processPortalArgs = portalModule._processPortalArgs
local yesno = require( 'Module:Yesno' )
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function sandboxVersion(s)
return isSandbox and s.."-sand" or s
end
-- Builds the portal bar used by {{portal bar}}.
function p._main( portals, args )
-- check for sensible args
args = type(args) == "table" and args or {}
-- Normalize arguments
for key, default in pairs({border=true,redlinks=false,tracking=true}) do
if args[key] == nil then args[key] = default end
args[key] = yesno(args[key], default)
end
local nav = mw.html.create( 'div' )
:addClass(sandboxVersion('portal-bar'))
:addClass( 'noprint metadata noviewer' )
:attr( 'role', 'navigation' )
:attr( 'aria-label' , 'Portals' )
:addClass(sandboxVersion(args.border and 'portal-bar-bordered' or 'portal-bar-unbordered'))
local trackingCat = ''
-- Allow any number of portals
args.minPortals = 0
args.maxPortals = -1
-- Check to see whether there are redlinks, filter out unless args.redlink is true
portals, trackingCat = checkPortals(portals, args)
nav:wikitext(trackingCat)
if #portals == 0 then
return trackingCat
end
local related = yesno(args.related)
if related then
nav:addClass(sandboxVersion('portal-bar-related'))
else
local header = nav:tag('span')
header:addClass(sandboxVersion('portal-bar-header'))
header:wikitext('[[Wikipedia:Contents/Portals|Portal]]')
if #portals > 1 then
header:wikitext('s')
end
header:wikitext(':')
end
local container = nav:tag('div')
container:addClass(sandboxVersion('portal-bar-content'))
if related then
container:addClass(sandboxVersion('portal-bar-content-related'))
end
local size = related and '27x25px' or '21x19px'
for _, portal in ipairs( portals ) do
container
:tag( 'span' )
:addClass(sandboxVersion('portal-bar-item'))
:wikitext( string.format('[[File:%s|%s]] [[Portal:%s|%s]]',
getImageName(portal,true), size, portal, portal))
end
local styleFile = 'Module:Portal bar'..sandbox..'/styles.css'
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = styleFile }
} .. tostring( nav )
end
-- Processes external arguments and sends them to the other functions.
function p.main( frame )
local origArgs = getArgs(frame)
local portals, args = processPortalArgs(origArgs)
return p._main( portals, args )
end
return p
bb586a960cb56daaef2c7b7c994afbbd94772bbd
Module:IPAc-en
828
81
177
2022-06-17T13:57:25Z
Canopus >Nardog
0
lang
Scribunto
text/plain
-- This module implements [[Template:IPAc-en]].
local data = mw.loadData('Module:IPAc-en/data')
local p = {}
-- Global container for tracking categories
local categoryHandler = require('Module:Category handler').main
local categories = {}
-- Trims whitespace from a string
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
-- This implements [[Template:Nowrap]].
local function makeNowrapSpan(s)
local span = mw.html.create('span')
:addClass('rt-commentedText') -- Works with [[MediaWiki:Gadget-ReferenceTooltips.js]]
:addClass('nowrap')
:wikitext(s)
return tostring(span)
end
local function makePronunciationText(id)
id = id and string.lower(trim(id))
if id and id ~= '' and data.pronunciation[id] then
return data.pronunciation[id].text
end
end
-- This adds a tooltip icon to a label. It implements [[Template:H:title]].
local function makeTooltip(label, tooltip)
local span = mw.html.create('span')
:attr('title', tooltip)
:wikitext(label)
return tostring(span)
end
local function formatPhonemeGroup(phonemes)
if #phonemes > 0 then
local span = mw.html.create('span')
:css('border-bottom', '1px dotted')
:wikitext(table.concat(phonemes))
return tostring(span)
else
return ''
end
end
local function renderCategories()
local ret = ''
if categoryHandler{ true } then
ret = {}
for cat in pairs(categories) do
table.insert(ret, string.format('[[Category:%s]]', cat))
end
table.sort(ret)
ret = table.concat(ret)
else
ret = ''
end
return ret
end
function p._main(args)
local ret = {}
local i = 0 -- Keeps track of numbered args
-- Pronunciation
do
local pron = {}
while true do
i = i + 1
local pronItem = makePronunciationText(args[i])
if pronItem then
pron[#pron + 1] = pronItem
pron[#pron + 1] = ' '
else
break
end
end
if #pron > 0 then
ret[#ret + 1] = string.format(
'<small>%s</small>',
table.concat(pron)
)
end
end
-- Phonemes
do
-- Loop through the numbered args, separating them into phoneme groups
-- and separator strings (both called "words" for convenience). We only
-- underline the phoneme groups, not the separators.
local words = {}
words[#words + 1] = '/' -- Opening slash
i = i - 1 -- Set up i again as it was changed in the pronunciation loop
local id
repeat
local phonemes = {}
local isWordEnd = false
while not isWordEnd do
i = i + 1
id = args[i]
id = id and trim(id)
if not id then
isWordEnd = true
words[#words + 1] = formatPhonemeGroup(phonemes)
elseif id ~= '' then
local t = data.phonemes[id]
if not t then
-- We were passed an invalid id.
isWordEnd = true
categories["Ill-formatted IPAc-en transclusions"] = true
words[#words + 1] = formatPhonemeGroup(phonemes)
words[#words + 1] = makeTooltip(
string.format(
"<strong class=\"error\">[invalid input: '%s']</strong>",
id
),
'Unrecognized symbol'
)
elseif not t.label then
-- The data module contains bad data, so throw an error.
error(string.format(
"no label was found for id '%s'",
tostring(id)
))
elseif t.tooltip then
-- We are dealing with a regular phoneme.
phonemes[#phonemes + 1] = makeTooltip(
t.label,
t.tooltip
)
else
-- We are dealing with a separator.
isWordEnd = true
words[#words + 1] = formatPhonemeGroup(phonemes)
words[#words + 1] = t.label
end
end
end
until not id
words[#words + 1] = '/' -- Closing slash
-- Wrap the words in a link to IPA help.
local span = mw.html.create('span')
-- Suppress Navigation popups and Page Previews (aka Hovercards)
:addClass('IPA nopopups noexcerpt')
:attr('lang', 'en-fonipa')
:wikitext(string.format(
'[[Help:IPA/English|%s]]',
table.concat(words)
))
ret[#ret + 1] = tostring(span)
end
-- Audio link
do
local file = args.audio and trim(args.audio)
if file and file ~= '' then
categories["Pages including recorded pronunciations"] = true
ret[#ret + 1] = mw.getCurrentFrame():expandTemplate{
title = 'Template:IPA audio link', args = { file, attribution = args.attribution } }
end
end
-- Nowrap and categories
ret = makeNowrapSpan(table.concat(ret)) .. renderCategories()
-- Reset the categories table in case we are run again.
categories = {}
return ret
end
function p.main(frame)
return p._main(frame:getParent().args)
end
return p
62c540dcdc647c5bc63614ba04eabf7f645dd284
Main Page
0
1
1
2022-06-21T21:45:07Z
MediaWiki default
1
Create main page
wikitext
text/x-wiki
__NOTOC__
== Welcome to {{SITENAME}}! ==
This Main Page was created automatically and it seems it hasn't been replaced yet.
=== For the bureaucrat(s) of this wiki ===
Hello, and welcome to your new wiki! Thank you for choosing Miraheze for the hosting of your wiki, we hope you will enjoy our hosting.
You can immediately start working on your wiki or whenever you want.
Need help? No problem! We will help you with your wiki as needed. To start, try checking out these helpful links:
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
==== I still don't understand X! ====
Well, that's no problem. Even if something isn't explained in the documentation/FAQ, we are still happy to help you. You can find us here:
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
=== For visitors of this wiki ===
Hello, the default Main Page of this wiki (this page) has not yet been replaced by the bureaucrat(s) of this wiki. The bureaucrat(s) might still be working on a Main Page, so please check again later!
21236ac3f8d65e5563b6da6b70815ca6bf1e6616
10
1
2022-06-23T13:02:34Z
SpaceMan
2
/* Welcome to AstroBase! */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
=== Miraheze ===
Hello, and welcome to your new wiki! Thank you for choosing Miraheze for the hosting of your wiki, we hope you will enjoy our hosting.
You can immediately start working on your wiki or whenever yo
Need help? No problem! We will help you with your wiki as needed. To start, try checking out these helpful links:
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
=== For visitors of this wiki ===
Hello, the default Main Page of this wiki (this page) has not yet been replaced by the bureaucrat(s) of this wiki. The bureaucrat(s) might still be working on a Main Page, so please check again later!
__INDEX__
__NEWSECTIONLINK__
30660bc82996a1236210ecb7a2998844cabc7032
11
10
2022-06-25T07:16:49Z
SpaceMan
2
/* Miraheze */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
=== Miraheze ===
your wiki as needed. To start, try checking out these helpful links:
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
=== For visitors of this wiki ===
Hello, the default Main Page of this wiki (this page) has not yet been replaced by the bureaucrat(s) of this wiki. The bureaucrat(s) might still be working on a Main Page, so please check again later!
__INDEX__
__NEWSECTIONLINK__
8dd8420a12b1aeb4e52c821af048315d0d558c0c
12
11
2022-06-25T07:17:35Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
781d5b730c902622fbe7aef268cc6e2528e4f032
13
12
2022-06-25T07:20:59Z
SpaceMan
2
Protected "[[Main Page]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
781d5b730c902622fbe7aef268cc6e2528e4f032
30
13
2022-07-02T03:39:22Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
===Quick List===
[[Special:ListUsers]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
bfca6b7c52b7e5922c1fa9ce6b3b8c4781465b1e
Template:FlowMention
10
2
2
2022-06-23T12:50:41Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
@[[User:{{{1|Example}}}|{{{2|{{{1|Example}}}}}}]]
98786e33cb63444ac23e3cf2bdbcab2d9501a6e7
Template:LQT Moved thread stub converted to Flow
10
3
3
2022-06-23T12:50:43Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
This post by {{{author}}} was moved on {{{date}}}. You can find it at [[{{{title}}}]].
792a92295d0603dc3cb5c46e15d4e42af9659414
Template:LQT page converted to Flow
10
4
4
2022-06-23T12:50:43Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
Previous page history was archived for backup purposes at <span class='flow-link-to-archive'>[[{{{archive}}}]]</span> on {{#time: Y-m-d|{{{date}}}}}.
c988d60d1df8c49bcce1f4f94a9c2a5318faf0d3
Template:Archive for converted LQT page
10
5
5
2022-06-23T12:50:44Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
This page is an archived LiquidThreads page. <strong>Do not edit the contents of this page</strong>. Please direct any additional comments to the [[{{{from}}}|current talk page]].
6f2232948be664f5eec18e4b7a6219814d38a478
Template:LQT post imported with suppressed user
10
6
6
2022-06-23T12:50:45Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
This revision was imported from LiquidThreads with a suppressed user. It has been reassigned to the current user.
0eb25fe53f4e146ddc0b16b14bd40d6069e56c06
Template:LQT post imported with different signature user
10
7
7
2022-06-23T12:50:46Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
<em>This post was posted by [[User:{{{authorUser}}}|{{{authorUser}}}]], but signed as [[User:{{{signatureUser}}}|{{{signatureUser}}}]].</em>
047294b02240e1b8526ad076eb47a07e98747bac
Template:Wikitext talk page converted to Flow
10
8
8
2022-06-23T12:50:47Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
Previous discussion was archived at <span class='flow-link-to-archive'>[[{{{archive}}}]]</span> on {{#time: Y-m-d|{{{date}}}}}.
69c9712008fdef423f0f0332a7d4ffcfe65e6e76
Template:Archive for converted wikitext talk page
10
9
9
2022-06-23T12:50:48Z
Flow talk page manager
3
/* Automatically created by Flow */
wikitext
text/x-wiki
This page is an archive. <strong>Do not edit the contents of this page</strong>. Please direct any additional comments to the [[{{{from|{{TALKSPACE}}:{{BASEPAGENAME}}}}}|current talk page]].
de059e2d945be0557b47d689299d8bd96e9699ed
Astronomy
0
10
14
2022-06-25T07:37:25Z
SpaceMan
2
Astronomy
wikitext
text/x-wiki
*Definition*
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and [[chemistry][ in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
[[File:Https://wallpapercave.com/wp/to2ELne.jpg|thumb|alt=Astronomy |Astronomy ]]
f0036893c0468ca7a25211fc6c19136284a7cc34
15
14
2022-06-25T07:38:17Z
SpaceMan
2
wikitext
text/x-wiki
**Definition**
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and [[chemistry][ in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
58c0adbf5c037ef5dd5859caf51f995e820b352a
16
15
2022-06-25T07:39:09Z
SpaceMan
2
wikitext
text/x-wiki
== Definition ==
*
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and [[chemistry][ in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
36bb58025d70aeb143f78d09b9173144d022677e
17
16
2022-06-25T07:39:32Z
SpaceMan
2
wikitext
text/x-wiki
== Definition ==
*
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and <nowiki>[[chemistry]]</nowiki>in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
41251f1d20d2d46adef9e54cc69fb38cc9a25906
19
17
2022-06-25T07:45:49Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
== Definition ==
*
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and <nowiki>[[chemistry]]</nowiki>in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
[[File:Astronomy.jpg|thumb|Astronomy picture]]
e89c3607361d4dcbc60666b4c807d95a0f4b0abe
File:Astronomy.jpg
6
11
18
2022-06-25T07:44:35Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=Astronomy picture}}
|date=2022-06-25
|source={{own}}
|author=[[User:SpaceMan|SpaceMan]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
[[Category:Astronomy pics]]
f2bd0fb0e8a5433da50d52f3832df75f9e600725
Acceleration
0
12
20
2022-06-25T15:21:03Z
SpaceMan
2
Acceleration
wikitext
text/x-wiki
==Definition==
It is defined as the change in the velocity of an object per unit time.
If the velocity of an object changes frIt is defined as the change in the om an initial value u to final value v in time t, then acceleration a is given by
Acceleration = (final velocity - initial velocity )/ Time
==Properties==
SI unit of acceleration is m/s²
It is a [https://wikiofspaceman.miraheze.org/wiki/Vector_quantity vector quantity], its direction is in the direction of change in velocity.
It may be positive, negative or zero.
If an object is moving with constant or uniform [[velocity]], then its acceleration is zero.
==Uniform acceleration==
A body is said to have uniform acceleration, if it travels in a straight line and its velocity increases or decreases by equal [[magnitude]] in equal intervals of time. For example :
(ii) The [[motion]] of a bicycle going down the slope of a road (when the rider is not pedaling and [[air resistance]] is negligible).
==Non-Uniform acceleration==
A body is said to have non-uniform acceleration, if its velocity changes by unequal magnitude in equal intervals of time.
For example - The motion of a car on a crowded road.
==Retardation or deceleration==
A body is said to be retarded if the magnitude of its velocity decreases with time. In this case, the final velocity of the moving body is less than the initial velocity i.e., v<u.
For example - When a person applies brake on a moving car, its velocity decreases with time. For example, if acceleration is a = - 5 m/s ^ 2 we can write this as the deceleration or retardation is taking place at 5 m/s² or you can also put it as acceleration in the opposite direction at the rate of 5 m/s².
7b0eebda6dbc4a0e447a95553cbe2dd800038524
21
20
2022-06-25T15:22:01Z
SpaceMan
2
/* Properties */
wikitext
text/x-wiki
==Definition==
It is defined as the change in the velocity of an object per unit time.
If the velocity of an object changes frIt is defined as the change in the om an initial value u to final value v in time t, then acceleration a is given by
Acceleration = (final velocity - initial velocity )/ Time
==Properties==
SI unit of acceleration is m/s²
It is a Vector quantity], its direction is in the direction of change in velocity.
It may be positive, negative or zero.
If an object is moving with constant or uniform [[velocity]], then its acceleration is zero.
==Uniform acceleration==
A body is said to have uniform acceleration, if it travels in a straight line and its velocity increases or decreases by equal [[magnitude]] in equal intervals of time. For example :
(ii) The [[motion]] of a bicycle going down the slope of a road (when the rider is not pedaling and [[air resistance]] is negligible).
==Non-Uniform acceleration==
A body is said to have non-uniform acceleration, if its velocity changes by unequal magnitude in equal intervals of time.
For example - The motion of a car on a crowded road.
==Retardation or deceleration==
A body is said to be retarded if the magnitude of its velocity decreases with time. In this case, the final velocity of the moving body is less than the initial velocity i.e., v<u.
For example - When a person applies brake on a moving car, its velocity decreases with time. For example, if acceleration is a = - 5 m/s ^ 2 we can write this as the deceleration or retardation is taking place at 5 m/s² or you can also put it as acceleration in the opposite direction at the rate of 5 m/s².
c4f0b1c84cd426997808a81b9f8e5eb76d02ea72
22
21
2022-06-25T15:22:21Z
SpaceMan
2
/* Properties */
wikitext
text/x-wiki
==Definition==
It is defined as the change in the velocity of an object per unit time.
If the velocity of an object changes frIt is defined as the change in the om an initial value u to final value v in time t, then acceleration a is given by
Acceleration = (final velocity - initial velocity )/ Time
==Properties==
SI unit of acceleration is m/s²
It is a [[Vector quantity]], its direction is in the direction of change in velocity.
It may be positive, negative or zero.
If an object is moving with constant or uniform [[velocity]], then its acceleration is zero.
==Uniform acceleration==
A body is said to have uniform acceleration, if it travels in a straight line and its velocity increases or decreases by equal [[magnitude]] in equal intervals of time. For example :
(ii) The [[motion]] of a bicycle going down the slope of a road (when the rider is not pedaling and [[air resistance]] is negligible).
==Non-Uniform acceleration==
A body is said to have non-uniform acceleration, if its velocity changes by unequal magnitude in equal intervals of time.
For example - The motion of a car on a crowded road.
==Retardation or deceleration==
A body is said to be retarded if the magnitude of its velocity decreases with time. In this case, the final velocity of the moving body is less than the initial velocity i.e., v<u.
For example - When a person applies brake on a moving car, its velocity decreases with time. For example, if acceleration is a = - 5 m/s ^ 2 we can write this as the deceleration or retardation is taking place at 5 m/s² or you can also put it as acceleration in the opposite direction at the rate of 5 m/s².
24354aacf7c5ca60b90e1d20bd9319a4b1ea48ea
Astrophysics
0
24
48
2022-06-26T08:22:32Z
Astrophysics >Citation bot
0
Add: bibcode. | [[WP:UCB|Use this bot]]. [[WP:DBUG|Report bugs]]. | Suggested by Abductive | #UCB_toolbar
wikitext
text/x-wiki
{{short description|Branch of astronomy}}
{{About|the use of physics to determine the nature of astronomical objects|the use of physics to determine their positions and motions|Celestial mechanics|the physical study of the largest-scale structures of the universe|Physical cosmology|the journal|Astrophysics (journal)}}
{{TopicTOC-Physics}}
'''Astrophysics''' is a science that employs the methods and principles of [[physics]] and [[chemistry]] in the study of [[astronomical object]]s and phenomena.<ref>{{cite book |title=Astrophysics in a Nutshell |first=Dan |last=Maoz |date=23 February 2016 |publisher=Princeton University Press |pages=272 |isbn=9781400881178 |url=https://www.google.com/books/edition/Astrophysics_in_a_Nutshell/bmBeCwAAQBAJ?hl=en&gbpv=1&dq=%22astrophysics+is%22&pg=PA1&printsec=frontcover}}</ref><ref>{{cite web | title=astrophysics | publisher=Merriam-Webster, Incorporated | url=http://www.merriam-webster.com/dictionary/astrophysics | access-date=2011-05-22 | archive-url= https://web.archive.org/web/20110610085146/http://www.merriam-webster.com/dictionary/astrophysics| archive-date= 10 June 2011 | url-status= live}}</ref> As one of the founders of the discipline said, Astrophysics "seeks to ascertain the nature of the heavenly bodies, rather than their positions or motions in space–''what'' they are, rather than ''where'' they are."<ref>{{Citation | last = Keeler | first = James E. | author-link = James E. Keeler | title = The Importance of Astrophysical Research and the Relation of Astrophysics to the Other Physical Sciences | journal = The Astrophysical Journal | volume = 6 | issue = 4 | pages = 271–288 | date = November 1897 | bibcode = 1897ApJ.....6..271K |doi = 10.1086/140401 | pmid = 17796068 }}</ref> Among the subjects studied are the [[Sun]], other [[star]]s, [[galaxy|galaxies]], [[extrasolar planet]]s, the [[interstellar medium]] and the [[cosmic microwave background]].<ref name="nasa.gov">{{cite web|url=https://science.nasa.gov/astrophysics/focus-areas/|title=Focus Areas – NASA Science|work=nasa.gov}}</ref><ref>{{cite encyclopedia|url=https://www.britannica.com/EBchecked/topic/40047/astronomy|title=astronomy|encyclopedia=Encyclopædia Britannica}}</ref> Emissions from these objects are examined across all parts of the [[electromagnetic spectrum]], and the properties examined include [[luminosity]], [[density]], [[temperature]], and [[chemistry|chemical]] composition. Because astrophysics is a very broad subject, ''astrophysicists'' apply concepts and methods from many disciplines of physics and chemistry, including [[classical mechanics]], [[electromagnetism]], [[statistical mechanics]], [[thermodynamics]], [[quantum mechanics]], [[theory of relativity|relativity]], [[nuclear physics|nuclear]] and [[particle physics]], and [[atomic, molecular, and optical physics|atomic and molecular physics]].
In practice, modern astronomical research often involves a substantial amount of work in the realms of [[Theoretical physics|theoretical]] and observational physics. Some areas of study for astrophysicists include their attempts to determine the properties of [[dark matter]], [[dark energy]], [[black holes]], and other [[celestial bodies]]; and the [[Cosmogony|origin]] and [[ultimate fate of the universe]].<ref name="nasa.gov"/> Topics also studied by theoretical astrophysicists include [[Formation and evolution of the Solar System|Solar System formation and evolution]]; [[stellar dynamics]] and [[Stellar evolution|evolution]]; [[galaxy formation and evolution]]; [[magnetohydrodynamics]]; [[large-scale structure of the universe|large-scale structure]] of [[matter]] in the universe; origin of [[cosmic ray]]s; [[general relativity]], [[special relativity]], [[quantum cosmology|quantum]] and [[physical cosmology]], including [[string theory|string]] cosmology and [[astroparticle physics]].
==History==
[[Image:NIEdot362.jpg|thumb|left|200px|Early 1900s comparison of elemental, solar, and stellar spectra]]
Astronomy is an ancient science, long separated from the study of terrestrial physics. In the [[Aristotle|Aristotelian]] worldview, bodies in the sky appeared to be unchanging [[Celestial spheres|spheres]] whose only motion was uniform motion in a circle, while the earthly world was the realm which underwent [[On Generation and Corruption|growth and decay]] and in which natural motion was in a straight line and ended when the moving object reached its [[Telos|goal]]. Consequently, it was held that the celestial region was made of a fundamentally different kind of matter from that found in the terrestrial sphere; either [[Fire (classical element)|Fire]] as maintained by [[Plato]], or [[Aether (classical element)|Aether]] as maintained by [[Aristotle#Physics|Aristotle]].<ref>{{cite book | last = Lloyd | first = G. E. R. | author-link = G. E. R. Lloyd | title = Aristotle: The Growth and Structure of His Thought | publisher = Cambridge University Press | year = 1968 | location = Cambridge | pages = [https://archive.org/details/aristotlegrowths0000lloy/page/134 134–135] | url =https://archive.org/details/aristotlegrowths0000lloy| url-access = registration | isbn = 978-0-521-09456-6}}</ref><ref>{{cite book | last = Cornford | first = Francis MacDonald | author-link = F. M. Cornford | title = Plato's Cosmology: The ''Timaeus'' of Plato translated, with a running commentary | publisher = Bobbs Merrill Co | date = c. 1957 | orig-year = 1937 | location = Indianapolis | page = 118}}</ref>
During the 17th century, natural philosophers such as [[Galileo]],<ref>{{Citation | last = Galilei | first = Galileo | author-link = Galileo Galilei | editor-last = Van Helden | editor-first = Albert | publication-date = 1989 | title = Sidereus Nuncius or The Sidereal Messenger | publisher = University of Chicago Press | location = Chicago | pages = 21, 47 | isbn = 978-0-226-27903-9 | date = 1989-04-15 }}</ref> [[Descartes]],<ref>{{Cite encyclopedia |author=Edward Slowik |title=Descartes' Physics |url=http://plato.stanford.edu/entries/descartes-physics/ |encyclopedia=[[Stanford Encyclopedia of Philosophy]] |date=2013 |orig-year=2005 |access-date=2015-07-18}}</ref> and [[Isaac Newton|Newton]]<ref>{{Citation | last = Westfall | first = Richard S. | author-link = Richard S. Westfall | publication-date = 1980 | title = Never at Rest: A Biography of Isaac Newton | publisher = Cambridge University Press | location = Cambridge | pages = [https://archive.org/details/neveratrestbiogr00west/page/731 731–732] | isbn = 978-0-521-27435-7 | date = 1983-04-29 | url-access = registration | url = https://archive.org/details/neveratrestbiogr00west/page/731 }}</ref> began to maintain that the celestial and terrestrial regions were made of similar kinds of material and were subject to the same [[Physical law|natural laws]].<ref name = Burtt/> Their challenge was that the tools had not yet been invented with which to prove these assertions.<ref>{{Cite journal |author=Ladislav Kvasz |title=Galileo, Descartes, and Newton – Founders of the Language of Physics |url=http://www.physics.sk/aps/pubs/2012/aps-12-06/aps-12-06.pdf |publisher=Institute of Philosophy, [[Academy of Sciences of the Czech Republic]] |date=2013 |access-date=2015-07-18}}</ref>
For much of the nineteenth century, astronomical research was focused on the routine work of measuring the positions and computing the motions of astronomical objects.<ref>{{Citation | last = Case | first = Stephen | date = 2015 | title = 'Land-marks of the universe': John Herschel against the background of positional astronomy | journal = Annals of Science | volume = 72 | issue = 4 | pages = 417–434 | doi = 10.1080/00033790.2015.1034588 | pmid = 26221834 | quote = The great majority of astronomers working in the early nineteenth century were not interested in stars as physical objects. Far from being bodies with physical properties to be investigated, the stars were seen as markers measured in order to construct an accurate, detailed and precise background against which solar, lunar and planetary motions could be charted, primarily for terrestrial applications.|bibcode = 2015AnSci..72..417C | doi-access = free }}</ref><ref>{{Citation | last = Donnelly | first = Kevin | date = September 2014 | title = On the boredom of science: positional astronomy in the nineteenth century | journal = The British Journal for the History of Science | volume = 47 | issue = 3 | pages = 479–503 | doi = 10.1017/S0007087413000915 | s2cid = 146382057 | url = https://zenodo.org/record/999531 }}</ref> A new astronomy, soon to be called astrophysics, began to emerge when [[William Hyde Wollaston]] and [[Joseph von Fraunhofer]] independently discovered that, when decomposing the light from the Sun, a multitude of [[Fraunhofer lines|dark lines]] (regions where there was less or no light) were observed in the [[Visible spectrum|spectrum]].<ref>{{cite book | last=Hearnshaw|first=J.B. | title=The analysis of starlight | date=1986 | publisher=Cambridge University Press | location=Cambridge | isbn=978-0-521-39916-6 | pages=23–29}}</ref> By 1860 the physicist, [[Gustav Kirchhoff]], and the chemist, [[Robert Bunsen]], had demonstrated that the [[Absorption spectroscopy#Absorption spectrum|dark lines]] in the solar spectrum corresponded to [[Emission spectrum|bright lines]] in the spectra of known gases, specific lines corresponding to unique [[chemical element]]s.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff |title=Ueber die Fraunhofer'schen Linien | journal=Annalen der Physik | volume=185 |issue=1 | pages=148–150 | date=1860 | bibcode = 1860AnP...185..148K | doi=10.1002/andp.18601850115| url = https://zenodo.org/record/1423666 }}</ref> Kirchhoff deduced that the dark lines in the solar spectrum are caused by [[absorption (optics)|absorption]] by [[chemical elements]] in the Solar atmosphere.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff | title=Ueber das Verhältniss zwischen dem Emissionsvermögen und dem Absorptionsvermögen der Körper für Wärme und Licht |journal=Annalen der Physik |volume=185 | issue=2 | pages=275–301 | date=1860 | bibcode = 1860AnP...185..275K | doi=10.1002/andp.18601850205| url=https://zenodo.org/record/1423668 | doi-access=free }}</ref> In this way it was proved that the chemical elements found in the Sun and stars were also found on Earth.
Among those who extended the study of solar and stellar spectra was [[Norman Lockyer]], who in 1868 detected radiant, as well as dark lines in solar spectra. Working with chemist [[Edward Frankland]] to investigate the spectra of elements at various temperatures and pressures, he could not associate a yellow line in the solar spectrum with any known elements. He thus claimed the line represented a new element, which was called [[helium]], after the Greek [[Helios]], the Sun personified.<ref>{{citation | last = Cortie | first = A. L. | title = Sir Norman Lockyer, 1836 – 1920 | journal = The Astrophysical Journal | year = 1921 | volume = 53 | pages = 233–248 | bibcode = 1921ApJ....53..233C | doi=10.1086/142602}}</ref><ref>{{Citation | last = Jensen | first = William B.|author1-link=William B. Jensen | title = Why Helium Ends in "-ium" | journal = Journal of Chemical Education | volume = 81 | issue = 7 | pages = 944–945 | year = 2004 | url = http://www.che.uc.edu/jensen/W.%20B.%20Jensen/Reprints/115.%20Helium.pdf | doi=10.1021/ed081p944 | bibcode = 2004JChEd..81..944J }}</ref>
In 1885, [[Edward C. Pickering]] undertook an ambitious program of stellar spectral classification at [[Harvard College Observatory]], in which a team of [[Harvard Computers|woman computers]], notably [[Williamina Fleming]], [[Antonia Maury]], and [[Annie Jump Cannon]], classified the spectra recorded on photographic plates. By 1890, a catalog of over 10,000 stars had been prepared that grouped them into thirteen spectral types. Following Pickering's vision, by 1924 Cannon expanded the [[Henry Draper Catalogue|catalog]] to nine volumes and over a quarter of a million stars, developing the [[Stellar classification#Harvard spectral classification|Harvard Classification Scheme]] which was accepted for worldwide use in 1922.<ref>{{Citation|last1=Hetherington |first1=Norriss S. |last2=McCray |first2=W. Patrick |author2-link=W. Patrick McCray |editor-last=Weart |editor-first=Spencer R. |editor-link=Spencer R. Weart |title=Spectroscopy and the Birth of Astrophysics |publisher=American Institute of Physics, Center for the History of Physics |url=https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |access-date=July 19, 2015 |url-status=dead |archive-url=https://web.archive.org/web/20150907133751/https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |archive-date=September 7, 2015 }}</ref>
In 1895, [[George Ellery Hale]] and [[James E. Keeler]], along with a group of ten associate editors from Europe and the United States,<ref name = Hale1895>{{Citation | last = Hale | first = George Ellery | title = The Astrophysical Journal | author-link = George Ellery Hale | journal = The Astrophysical Journal | volume = 1 | issue = 1 | pages = 80–84 | bibcode = 1895ApJ.....1...80H | doi = 10.1086/140011| year = 1895 }}</ref> established [[The Astrophysical Journal|''The Astrophysical Journal: An International Review of Spectroscopy and Astronomical Physics'']].<ref>{{List journal | journal = The Astrophysical Journal | volume = 1 | issue = 1 }}</ref> It was intended that the journal would fill the gap between journals in astronomy and physics, providing a venue for publication of articles on astronomical applications of the spectroscope; on laboratory research closely allied to astronomical physics, including wavelength determinations of metallic and gaseous spectra and experiments on radiation and absorption; on theories of the Sun, Moon, planets, comets, meteors, and nebulae; and on instrumentation for telescopes and laboratories.<ref name = Hale1895/>
Around 1920, following the discovery of the [[Hertzsprung–Russell diagram]] still used as the basis for classifying stars and their evolution, [[Arthur Eddington]] anticipated the discovery and mechanism of [[nuclear fusion]] processes in [[star]]s, in his paper ''The Internal Constitution of the Stars''.<ref name=eddington> {{ Citation | last = Eddington | first = A. S. | author-link = Arthur Eddington | date = October 1920 | title = The Internal Constitution of the Stars | journal = The Scientific Monthly | volume = 11 | issue = 4 | pages = 297–303 | doi = 10.1126/science.52.1341.233 | jstor = 6491 | pmid = 17747682 | bibcode = 1920Sci....52..233E | url = https://zenodo.org/record/1429642 }}</ref><ref name=eddington2>{{cite journal | bibcode = 1916MNRAS..77...16E | title = On the radiative equilibrium of the stars | journal=Monthly Notices of the Royal Astronomical Society | volume=77 | pages=16–35 | last1=Eddington|first1=A. S. | author-link = Arthur Eddington | year=1916 | doi=10.1093/mnras/77.1.16| doi-access=free }}</ref> At that time, the source of stellar energy was a complete mystery; Eddington correctly speculated that the source was [[nuclear fusion|fusion]] of hydrogen into helium, liberating enormous energy according to Einstein's equation ''E = mc<sup>2</sup>''. This was a particularly remarkable development since at that time fusion and thermonuclear energy, and even that stars are largely composed of [[hydrogen]] (see [[metallicity]]), had not yet been discovered.<ref>{{Cite book|title=Fusion|last1=McCracken|editor-last2=Stott|editor-first2=Peter|editor-last=McCracken|editor-first=Garry|last2=Stott|first2=Peter|first1=Garry|url=http://www.sciencedirect.com/science/article/pii/B9780123846563000027|language=en|doi=10.1016/b978-0-12-384656-3.00002-7|pages=13|isbn=978-0-12-384656-3|location=Boston|date=2013-01-01|publisher=Academic Press|quote=Eddington had realized that there would be a mass loss if four hydrogen atoms combined to form a single helium atom. Einstein’s equivalence of mass and energy led directly to the suggestion that this could be the long-sought process that produces the energy in the stars! It was an inspired guess, all the more remarkable because the structure of the nucleus and the mechanisms of these reactions were not fully understood.|edition=Second}}</ref>
In 1925 Cecilia Helena Payne (later [[Cecilia Payne-Gaposchkin]]) wrote an influential doctoral dissertation at [[Radcliffe College]], in which she applied ionization theory to stellar atmospheres to relate the spectral classes to the temperature of stars.<ref>{{citation |last=Payne |first=C. H. |year=1925 |title=Stellar Atmospheres; A Contribution to the Observational Study of High Temperature in the Reversing Layers of Stars |type=PhD Thesis |publisher=[[Radcliffe College]] | location = Cambridge, Massachusetts | publication-date = 1925 |bibcode=1925PhDT.........1P }}</ref> Most significantly, she discovered that hydrogen and helium were the principal components of stars. Despite Eddington's suggestion, this discovery was so unexpected that her dissertation readers convinced her to modify the conclusion before publication. However, later research confirmed her discovery.<ref>{{citation | last = Haramundanis | first = Katherine | editor-last = Hockey | editor-first = Thomas | editor2-last = Trimble | editor2-first = Virginia | editor2-link = Virginia Louise Trimble | editor3-last = Williams | editor3-first = Thomas R. | title = Biographical Encyclopedia of Astronomers | chapter = Payne-Gaposchkin [Payne], Cecilia Helena | access-date = July 19, 2015 |year=2007 | chapter-url=https://books.google.com/books?id=t-BF1CHkc50C | pages=876–878 | publisher = Springer | location = New York | isbn = 978-0-387-30400-7 }}</ref>
By the end of the 20th century, studies of astronomical spectra had expanded to cover wavelengths extending from radio waves through optical, x-ray, and gamma wavelengths.<ref>{{cite conference |mode=cs2 |last1=Biermann |first1=Peter L. |last2=Falcke |first2=Heino |author2-link=Heino Falcke |editor-last=Panvini |editor-first=Robert S. |editor2-last=Weiler |editor2-first=Thomas J. |date=1998 |book-title=Fundamental particles and interactions: Frontiers in contemporary physics an international lecture and workshop series. AIP Conference Proceedings |title=Frontiers of Astrophysics: Workshop Summary |volume=423 |publisher=American Institute of Physics |pages=236–248 |isbn=1-56396-725-1 |bibcode=1998AIPC..423..236B |doi=10.1063/1.55085|arxiv=astro-ph/9711066 }}</ref> In the 21st century, it further expanded to include observations based on [[gravitational waves]].
==Observational astrophysics==
[[Image:N 63A- Chandra and Hubble - Heic0507f.tif|thumb|right|200px|Supernova remnant LMC N 63A imaged in x-ray (blue), optical (green) and radio (red) wavelengths. The X-ray glow is from material heated to about ten million degrees Celsius by a shock wave generated by the supernova explosion.]]
[[Observational astronomy]] is a division of the astronomical science that is concerned with recording and interpreting data, in contrast with [[theoretical astrophysics]], which is mainly concerned with finding out the measurable implications of physical [[model (abstract)|models]]. It is the practice of observing [[celestial object]]s by using [[telescope]]s and other astronomical apparatus.
The majority of astrophysical observations are made using the [[electromagnetic spectrum]].
* [[Radio astronomy]] studies radiation with a [[wavelength]] greater than a few millimeters. Example areas of study are [[radio waves]], usually emitted by cold objects such as [[interstellar gas]] and dust clouds; the cosmic microwave background radiation which is the [[redshift]]ed light from the [[Big Bang]]; [[pulsar]]s, which were first detected at [[microwave]] frequencies. The study of these waves requires very large [[radio telescope]]s.
* [[Infrared astronomy]] studies radiation with a wavelength that is too long to be visible to the naked eye but is shorter than radio waves. Infrared observations are usually made with telescopes similar to the familiar [[optical]] telescopes. Objects colder than stars (such as planets) are normally studied at infrared frequencies.
* [[Optical astronomy]] was the earliest kind of astronomy. Telescopes paired with a [[charge-coupled device]] or [[spectroscope]]s are the most common instruments used. The Earth's [[atmosphere]] interferes somewhat with optical observations, so [[adaptive optics]] and [[space telescope]]s are used to obtain the highest possible image quality. In this wavelength range, stars are highly visible, and many chemical spectra can be observed to study the chemical composition of stars, galaxies, and [[nebula]]e.
* [[Ultraviolet]], [[X-ray astronomy|X-ray]] and [[gamma ray astronomy]] study very energetic processes such as [[binary pulsar]]s, [[black hole]]s, [[magnetar]]s, and many others. These kinds of radiation do not penetrate the Earth's atmosphere well. There are two methods in use to observe this part of the electromagnetic spectrum—[[space-based telescope]]s and ground-based [[imaging air Cherenkov telescope]]s (IACT). Examples of [[Observatory|Observatories]] of the first type are [[RXTE]], the [[Chandra X-ray Observatory]] and the [[Compton Gamma Ray Observatory]]. Examples of IACTs are the [[High Energy Stereoscopic System]] (H.E.S.S.) and the [[MAGIC (telescope)|MAGIC]] telescope.
Other than electromagnetic radiation, few things may be observed from the Earth that originate from great distances. A few [[gravitational wave]] observatories have been constructed, but gravitational waves are extremely difficult to detect. [[Neutrino]] observatories have also been built, primarily to study our Sun. Cosmic rays consisting of very high-energy particles can be observed hitting the Earth's atmosphere.
Observations can also vary in their time scale. Most optical observations take minutes to hours, so phenomena that change faster than this cannot readily be observed. However, historical data on some objects is available, spanning [[century|centuries]] or [[millennia]]. On the other hand, radio observations may look at events on a millisecond timescale ([[millisecond pulsar]]s) or combine years of data ([[Rotation-powered pulsar|pulsar deceleration]] studies). The information obtained from these different timescales is very different.
The study of our very own Sun has a special place in observational astrophysics. Due to the tremendous distance of all other stars, the Sun can be observed in a kind of detail unparalleled by any other star. Our understanding of our own Sun serves as a guide to our understanding of other stars.
The topic of how stars change, or stellar evolution, is often modeled by placing the varieties of star types in their respective positions on the [[Hertzsprung–Russell diagram]], which can be viewed as representing the state of a stellar object, from birth to destruction.
==Theoretical astrophysics==
{{see also|Theoretical astronomy}}
Theoretical astrophysicists use a wide variety of tools which include [[mathematical model|analytical models]] (for example, [[polytrope]]s to approximate the behaviors of a star) and [[computation]]al [[Numerical analysis|numerical simulations]]. Each has some advantages. Analytical models of a process are generally better for giving insight into the heart of what is going on. Numerical models can reveal the existence of phenomena and effects that would otherwise not be seen.<ref>{{Citation |first=H. |last=Roth |title=A Slowly Contracting or Expanding Fluid Sphere and its Stability |journal=[[Physical Review]] |volume=39 |issue=3 |pages=525–529 |year=1932 |doi=10.1103/PhysRev.39.525 |bibcode = 1932PhRv...39..525R }}</ref><ref>{{Citation |first=A.S. |last=Eddington |title=Internal Constitution of the Stars |journal=Science |location=New York |publisher=Cambridge University Press |orig-year=1926 |year=1988 |volume=52 |issue=1341 |pages=233–240 |doi=10.1126/science.52.1341.233 |isbn=978-0-521-33708-3 |pmid=17747682 |bibcode=1920Sci....52..233E |url=https://zenodo.org/record/1429642 }}</ref>
Theorists in astrophysics endeavor to create theoretical models and figure out the observational consequences of those models. This helps allow observers to look for data that can refute a model or help in choosing between several alternate or conflicting models.
Theorists also try to generate or modify models to take into account new data. In the case of an inconsistency, the general tendency is to try to make minimal modifications to the model to fit the data. In some cases, a large amount of inconsistent data over time may lead to total abandonment of a model.
Topics studied by theoretical astrophysicists include stellar dynamics and evolution; galaxy formation and evolution; magnetohydrodynamics; large-scale structure of matter in the universe; origin of cosmic rays; general relativity and physical cosmology, including [[string theory|string]] cosmology and astroparticle physics. Astrophysical relativity serves as a tool to gauge the properties of large-scale structures for which gravitation plays a significant role in physical phenomena investigated and as the basis for [[black hole]] (''astro'')physics and the study of [[gravitational waves]].
Some widely accepted and studied theories and models in astrophysics, now included in the [[Lambda-CDM model]], are the [[Big Bang]], [[cosmic inflation]], dark matter, dark energy and fundamental theories of physics.
== Popularization ==
The roots of astrophysics can be found in the seventeenth century emergence of a unified physics, in which the same laws applied to the celestial and terrestrial realms.<ref name = Burtt>{{Citation | last = Burtt | first = Edwin Arthur | author-link = Edwin Arthur Burtt | publication-date = 2003 | orig-year = First published 1924 | title = The Metaphysical Foundations of Modern Science | edition = second revised | publisher = Dover Publications | location = Mineola, NY | pages = 30, 41, 241–2 | isbn = 978-0-486-42551-1 | url = https://books.google.com/books?id=G9WBMa1Rz_kC | year = 2003 }}</ref> There were scientists who were qualified in both physics and astronomy who laid the firm foundation for the current science of astrophysics. In modern times, students continue to be drawn to astrophysics due to its popularization by the [[Royal Astronomical Society]] and notable [[Science education|educators]] such as prominent professors [[Lawrence Krauss]], [[Subrahmanyan Chandrasekhar]], [[Stephen Hawking]], [[Hubert Reeves]], [[Carl Sagan]], [[Neil deGrasse Tyson]] and [[Patrick Moore]]. The efforts of the early, late, and present scientists continue to attract young people to study the history and science of astrophysics.<ref>{{Cite web |author=D. Mark Manley |title=Famous Astronomers and Astrophysicists |url=http://cnr2.kent.edu/~manley/astronomers.html |publisher=[[Kent State University]] |date=2012 |access-date=2015-07-17}}</ref><ref>{{Cite web |author=The science.ca team |title=Hubert Reeves – Astronomy, Astrophysics and Space Science |url=http://www.science.ca/scientists/scientistprofile.php?pID=213 |publisher=GCS Research Society |date=2015 |access-date=2015-07-17}}</ref><ref>{{Cite web |title=Neil deGrasse Tyson |url=http://www.haydenplanetarium.org/tyson/ |publisher=[[Hayden Planetarium]] |date=2015 |access-date=2015-07-17}}</ref>
==See also==
{{cols|colwidth=21em}}
* [[Astrochemistry]]
* [[List of astronomical observatories|Astronomical observatories]]
* [[Astronomical spectroscopy]]
* [[Astroparticle physics]]
* [[Gravitational-wave astronomy]]
* [[Hertzsprung–Russell diagram]]
* [[High-energy astronomy]]
* [[List of important publications in physics#Astrophysics|Important publications in astrophysics]]
* [[List of astronomers]] (includes astrophysicists)
* [[Neutrino astronomy]] (future prospects)
* [[Timeline of gravitational physics and relativity]]
* [[Timeline of knowledge about galaxies, clusters of galaxies, and large-scale structure]]
* [[Timeline of white dwarfs, neutron stars, and supernovae]]
{{colend}}
==References==
{{Reflist}}
==Further reading==
* {{Citation | last = Longair | first = Malcolm S. | author-link = Malcolm S. Longair | title = The Cosmic Century: A History of Astrophysics and Cosmology | place = Cambridge | publisher = Cambridge University Press | year = 2006 | isbn = 978-0-521-47436-8 | url-access = registration | url = https://archive.org/details/cosmiccenturyhis0000long }}
* [http://www.scholarpedia.org/article/Encyclopedia:Astrophysics Astrophysics] [[Scholarpedia]] Expert articles
==External links==
{{Wikibooks|Astrophysics}}
{{Library resources box|onlinebooks=yes}}
* [http://www.aanda.org/ ''Astronomy and Astrophysics'', a European Journal]
* [http://iopscience.iop.org/0004-637X/ ''Astrophysical Journal'']
* [http://www.aip.org/history/cosmology/index.htm Cosmic Journey: A History of Scientific Cosmology] from the American Institute of Physics
* [http://www.worldscinet.com/ijmpd/ijmpd.shtml ''International Journal of Modern Physics D''] from [[World Scientific]]
* [http://www.scienceresourceworld.com/publications/journals/astronomy_journals.html List and directory of peer-reviewed Astronomy / Astrophysics Journals]
* [http://www.astro.ucla.edu/~wright/cosmolog.htm Ned Wright's Cosmology Tutorial, UCLA]
{{Physics-footer}}
{{Astronomy subfields}}
{{Astronomy navbox}}
{{Portal bar|Physics|Astronomy|Stars|Spaceflight|Outer space|Solar System}}
{{Authority control}}
[[Category:Astrophysics| ]]
[[Category:Astronomical sub-disciplines]]
bd2c54352b5f33382b25fe37da4e112ea4e9afdc
Module:Val
828
43
101
2022-06-30T03:19:56Z
Canopus >Johnuniq
0
use i18n from [[Module:Val/sandbox]] added by [[User:Moroboshi]]
Scribunto
text/plain
-- For Template:Val, output a number and optional unit.
-- Format options include scientific and uncertainty notations.
local numdot = '.' -- decimal mark (use ',' for Italian)
local numsep = ',' -- group separator (use ' ' for Italian)
local mtext = {
-- Message and other text that should be localized.
['mt-bad-exponent'] = 'exponent parameter (<b>e</b>)',
['mt-parameter'] = 'parameter ',
['mt-not-number'] = 'is not a valid number',
['mt-cannot-range'] = 'cannot use a range if the first parameter includes "e"',
['mt-need-range'] = 'needs a range in parameter 2',
['mt-should-range'] = 'should be a range',
['mt-cannot-with-e'] = 'cannot be used if the first parameter includes "e"',
['mt-not-range'] = 'does not accept a range',
['mt-cannot-e'] = 'cannot use e notation',
['mt-too-many-parameter'] = 'too many parameters',
['mt-need-number'] = 'need a number after the last parameter because it is a range.',
['mt-ignore-parameter4'] = 'Val parameter 4 ignored',
['mt-val-not-supported'] = 'Val parameter "%s=%s" is not supported',
['mt-invalid-scale'] = 'Unit "%s" has invalid scale "%s"',
['mt-both-u-ul'] = 'unit (<b>u</b>) and unit with link (<b>ul</b>) are both specified, only one is allowed.',
['mt-both-up-upl'] = 'unit per (<b>up</b>) and unit per with link (<b>upl</b>) are both specified, only one is allowed.',
}
local data_module = 'Module:Val/units'
local convert_module = 'Module:Convert'
local function valerror(msg, nocat, iswarning)
-- Return formatted message text for an error or warning.
-- Can append "#FormattingError" to URL of a page with a problem to find it.
local anchor = '<span id="FormattingError"></span>'
local body, category
if nocat or mw.title.getCurrentTitle():inNamespaces(1, 2, 3, 5) then
-- No category in Talk, User, User_talk, or Wikipedia_talk.
category = ''
else
category = '[[Category:Pages with incorrect formatting templates use]]'
end
iswarning = false -- problems are infrequent so try showing large error so editor will notice
if iswarning then
body = '<sup class="noprint Inline-Template" style="white-space:nowrap;">' ..
'[[Template:Val|<span title="' ..
msg:gsub('"', '"') ..
'">warning</span>]]</sup>'
else
body = '<strong class="error">' ..
'Error in {{[[Template:val|val]]}}: ' ..
msg ..
'</strong>'
end
return anchor .. body .. category
end
local range_types = {
-- No need for ' ' because nowrap applies to all output.
[","] = ", ",
["by"] = " by ",
["-"] = "–",
["–"] = "–",
["and"] = " and ",
["or"] = " or " ,
["to"] = " to " ,
["x"] = " × ",
["×"] = " × ",
["/"] = "/",
}
local range_repeat_unit = {
-- WP:UNIT wants unit repeated when a "multiply" range is used.
["x"] = true,
["×"] = true,
}
local function extract_item(index, numbers, arg)
-- Extract an item from arg and store the result in numbers[index].
-- If no argument or if argument is valid, return nil (no error);
-- otherwise, return an error message.
-- The stored result is:
-- * a table for a number (empty if there was no specified number); or
-- * a string for range text
-- Input like 1e3 is regarded as invalid for all except argument 1
-- which accepts e notation as an alternative to the 'e' argument.
-- Input group separators are removed.
local which = index
local function fail(msg)
local description
if which == 'e' then
description = mtext['mt-bad-exponent']
else
description = mtext['mt-parameter'] .. which
end
return description .. ' ' .. (msg or mtext['mt-not-number']) .. '.'
end
local result = {}
local range = range_types[arg]
if range then
if type(index) == 'number' and (index % 2 == 0) then
if index == 2 then
if numbers[1] and numbers[1].exp then
return fail(mtext['mt-cannot-range'])
end
numbers.has_ranges = true
else
if not numbers.has_ranges then
return fail(mtext['mt-need-range'])
end
end
numbers[index] = range
if range_repeat_unit[arg] then
-- Any "repeat" range forces unit (if any) to be repeated for all items.
numbers.isrepeat = true
end
return nil
end
return fail(mtext['mt-not-range'])
end
if numbers.has_ranges and type(index) == 'number' and (index % 2 == 0) then
return fail(mtext['mt-should-range'])
end
if index == 'e' then
local e = numbers[1] and numbers[1].exp
if e then
if arg then
return fail(mtext['mt-cannot-with-e'])
end
arg = e
which = 1
end
end
if arg and arg ~= '' then
arg = arg:gsub(numsep, '')
if numdot ~= '.' then
arg = arg:gsub(numdot, '.')
end
if arg:sub(1, 1) == '(' and arg:sub(-1) == ')' then
result.parens = true
arg = arg:sub(2, -2)
end
local a, b = arg:match('^(.+)[Ee](.+)$')
if a then
if index == 1 then
arg = a
result.exp = b
else
return fail(mtext['mt-cannot-e'])
end
end
local isnegative, propersign, prefix
local minus = '−'
prefix, arg = arg:match('^(.-)([%d.]+)$')
local value = tonumber(arg)
if not value then
return fail()
end
if arg:sub(1, 1) == '.' then
arg = '0' .. arg
end
if prefix == '' then
-- Ignore.
elseif prefix == '±' then
-- Display for first number, ignore for others.
if index == 1 then
propersign = '±'
end
elseif prefix == '+' then
propersign = '+'
elseif prefix == '-' or prefix == minus then
propersign = minus
isnegative = true
else
return fail()
end
result.clean = arg
result.sign = propersign or ''
result.value = isnegative and -value or value
end
numbers[index] = result
return nil -- no error
end
local function get_args(numbers, args)
-- Extract arguments and store the results in numbers.
-- Return nothing (no error) if ok; otherwise, return an error message.
for index = 1, 99 do
local which = index
local arg = args[which] -- has been trimmed
if not arg then
which = 'e'
arg = args[which]
end
local msg = extract_item(which, numbers, arg)
if msg then
return msg
end
if which == 'e' then
break
end
if index > 19 then
return mtext['mt-too-many-parameter']
end
end
if numbers.has_ranges and (#numbers % 2 == 0) then
return mtext['mt-need-number']
end
end
local function get_scale(text, ucode)
-- Return the value of text as a number, or throw an error.
-- This supports extremely basic expressions of the form:
-- a / b
-- a ^ b
-- where a and b are numbers or 'pi'.
local n = tonumber(text)
if n then
return n
end
n = text:gsub('pi', math.pi)
for _, op in ipairs({ '/', '^' }) do
local a, b = n:match('^(.-)' .. op .. '(.*)$')
if a then
a = tonumber(a)
b = tonumber(b)
if a and b then
if op == '/' then
return a / b
elseif op == '^' then
return a ^ b
end
end
break
end
end
error(string.format(mtext['mt-invalid-scale'], ucode, text))
end
local function get_builtin_unit(ucode, definitions)
-- Return table of information for the specified built-in unit, or nil if not known.
-- Each defined unit code must be followed by two spaces (not tab characters).
local _, pos = definitions:find('\n' .. ucode .. ' ', 1, true)
if pos then
local endline = definitions:find('%s*\n', pos)
if endline then
local result = {}
local n = 0
local text = definitions:sub(pos + 1, endline - 1):gsub('%s%s+', '\t')
for item in (text .. '\t'):gmatch('(%S.-)\t') do
if item == 'ALIAS' then
result.alias = true
elseif item == 'ANGLE' then
result.isangle = true
result.nospace = true
elseif item == 'NOSPACE' then
result.nospace = true
elseif item == 'SI' then
result.si = true
else
n = n + 1
if n == 1 then
local link, symbol = item:match('^%[%[([^|]+)|(.+)%]%]$')
if link then
result.symbol = symbol
result.link = link
n = 2
else
result.symbol = item
end
elseif n == 2 then
result.link = item
elseif n == 3 then
result.scale_text = item
result.scale = get_scale(item, ucode)
else
result.more_ignored = item
break
end
end
end
if result.si then
local s = result.symbol
if ucode == 'mc' .. s or ucode == 'mu' .. s then
result.ucode = 'µ' .. s -- unit code for convert should be this
end
end
if n >= 2 or (n >= 1 and result.alias) then
return result
end
-- Ignore invalid definition, treating it as a comment.
end
end
end
local function convert_lookup(ucode, value, scaled_top, want_link, si, options)
local lookup = require(convert_module)._unit
return lookup(ucode, {
value = value,
scaled_top = scaled_top,
link = want_link,
si = si,
sort = options.sortable,
})
end
local function get_unit(ucode, value, scaled_top, options)
local want_link = options.want_link
if scaled_top then
want_link = options.want_per_link
end
local data = mw.loadData(data_module)
local result = options.want_longscale and
get_builtin_unit(ucode, data.builtin_units_long_scale) or
get_builtin_unit(ucode, data.builtin_units)
local si, use_convert
if result then
if result.alias then
ucode = result.symbol
use_convert = true
end
if result.scale then
-- Setting si means convert will use the unit as given, and the sort key
-- will be calculated from the value without any extra scaling that may
-- occur if convert found the unit code. For example, if val defines the
-- unit 'year' with a scale and if si were not set, convert would also apply
-- its own scale because convert knows that a year is 31,557,600 seconds.
si = { result.symbol, result.link }
value = value * result.scale
end
if result.si then
ucode = result.ucode or ucode
si = { result.symbol, result.link }
use_convert = true
end
else
result = {}
use_convert = true
end
local convert_unit = convert_lookup(ucode, value, scaled_top, want_link, si, options)
result.sortkey = convert_unit.sortspan
if use_convert then
result.text = convert_unit.text
result.scaled_top = convert_unit.scaled_value
else
if want_link then
result.text = '[[' .. result.link .. '|' .. result.symbol .. ']]'
else
result.text = result.symbol
end
result.scaled_top = value
end
return result
end
local function makeunit(value, options)
-- Return table of information for the requested unit and options, or
-- return nil if no unit.
options = options or {}
local unit
local ucode = options.u
local percode = options.per
if ucode then
unit = get_unit(ucode, value, nil, options)
elseif percode then
unit = { nospace = true, scaled_top = value }
else
return nil
end
local text = unit.text or ''
local sortkey = unit.sortkey
if percode then
local function bracketed(code, text)
return code:find('[*./]') and '(' .. text .. ')' or text
end
local perunit = get_unit(percode, 1, unit.scaled_top, options)
text = (ucode and bracketed(ucode, text) or '') ..
'/' .. bracketed(percode, perunit.text)
sortkey = perunit.sortkey
end
if not (unit.nospace or options.nospace) then
text = ' ' .. text
end
return { text = text, isangle = unit.isangle, sortkey = sortkey }
end
local function list_units(mode)
-- Return wikitext to list the built-in units.
-- A unit code should not contain wikimarkup so don't bother escaping.
local data = mw.loadData(data_module)
local definitions = data.builtin_units .. data.builtin_units_long_scale
local last_was_blank = true
local n = 0
local result = {}
local function add(line)
if line == '' then
last_was_blank = true
else
if last_was_blank and n > 0 then
n = n + 1
result[n] = ''
end
last_was_blank = false
n = n + 1
result[n] = line
end
end
local si_prefixes = {
-- These are the prefixes recognized by convert; u is accepted for micro.
y = 'y',
z = 'z',
a = 'a',
f = 'f',
p = 'p',
n = 'n',
u = 'µ',
['µ'] = 'µ',
m = 'm',
c = 'c',
d = 'd',
da = 'da',
h = 'h',
k = 'k',
M = 'M',
G = 'G',
T = 'T',
P = 'P',
E = 'E',
Z = 'Z',
Y = 'Y',
}
local function is_valid(ucode, unit)
if unit and not unit.more_ignored then
assert(type(unit.symbol) == 'string' and unit.symbol ~= '')
if unit.alias then
if unit.link or unit.scale_text or unit.si then
return false
end
end
if unit.si then
if unit.scale_text then
return false
end
ucode = unit.ucode or ucode
local base = unit.symbol
if ucode == base then
unit.display = base
return true
end
local plen = #ucode - #base
if plen > 0 then
local prefix = si_prefixes[ucode:sub(1, plen)]
if prefix and ucode:sub(plen + 1) == base then
unit.display = prefix .. base
return true
end
end
else
unit.display = unit.symbol
return true
end
end
return false
end
local lookup = require(convert_module)._unit
local function show_convert(ucode, unit)
-- If a built-in unit defines a scale or sets the SI flag, any unit defined in
-- convert is not used (the scale or SI prefix's scale is used for a sort key).
-- If there is no scale or SI flag, and the unit is not defined in convert,
-- the sort key may not be correct; this allows such units to be identified.
if not (unit.si or unit.scale_text) then
if mode == 'convert' then
unit.show = not lookup(unit.alias and unit.symbol or ucode).unknown
unit.show_text = 'CONVERT'
elseif mode == 'unknown' then
unit.show = lookup(unit.alias and unit.symbol or ucode).unknown
unit.show_text = 'UNKNOWN'
elseif not unit.alias then
-- Show convert's scale in square brackets ('[1]' for an unknown unit).
-- Don't show scale for an alias because it's misleading for temperature
-- and an alias is probably not useful for anything else.
local scale = lookup(ucode, {value=1, sort='on'}).scaled_value
if type(scale) == 'number' then
scale = string.format('%.5g', scale):gsub('e%+?(%-?)0*(%d+)', 'e%1%2')
else
scale = '?'
end
unit.show = true
unit.show_text = '[' .. scale .. ']'
end
end
end
for line in definitions:gmatch('([^\n]*)\n') do
local pos, _ = line:find(' ', 1, true)
if pos then
local ucode = line:sub(1, pos - 1)
local unit = get_builtin_unit(ucode, '\n' .. line .. '\n')
if is_valid(ucode, unit) then
show_convert(ucode, unit)
local flags, text
if unit.alias then
text = unit.symbol
else
text = '[[' .. unit.link .. '|' .. unit.display .. ']]'
end
if unit.isangle then
unit.nospace = nil -- don't show redundant flag
end
for _, f in ipairs({
{ 'alias', 'ALIAS' },
{ 'isangle', 'ANGLE' },
{ 'nospace', 'NOSPACE' },
{ 'si', 'SI' },
{ 'scale_text', unit.scale_text },
{ 'show', unit.show_text },
}) do
if unit[f[1]] then
local t = f[2]
if t:match('^%u+$') then
t = '<small>' .. t .. '</small>'
end
if flags then
flags = flags .. ' ' .. t
else
flags = t
end
end
end
if flags then
text = text .. ' • ' .. flags
end
add(ucode .. ' = ' .. text .. '<br />')
else
add(line .. ' ◆ <b>invalid definition</b><br />')
end
else
add(line)
end
end
return table.concat(result, '\n')
end
local delimit_groups = require('Module:Gapnum').groups
local function delimit(sign, numstr, fmt)
-- Return sign and numstr (unsigned digits or numdot only) after formatting.
-- Four-digit integers are not formatted with gaps.
fmt = (fmt or ''):lower()
if fmt == 'none' or (fmt == '' and #numstr == 4 and numstr:match('^%d+$')) then
return sign .. numstr
end
-- Group number by integer and decimal parts.
-- If there is no decimal part, delimit_groups returns only one table.
local ipart, dpart = delimit_groups(numstr)
local result
if fmt == 'commas' then
result = sign .. table.concat(ipart, numsep)
if dpart then
result = result .. numdot .. table.concat(dpart)
end
else
-- Delimit with a small gap by default.
local groups = {}
groups[1] = table.remove(ipart, 1)
for _, v in ipairs(ipart) do
table.insert(groups, '<span style="margin-left:.25em;">' .. v .. '</span>')
end
if dpart then
table.insert(groups, numdot .. (table.remove(dpart, 1) or ''))
for _, v in ipairs(dpart) do
table.insert(groups, '<span style="margin-left:.25em;">' .. v .. '</span>')
end
end
result = sign .. table.concat(groups)
end
return result
end
local function sup_sub(sup, sub, align)
-- Return the same result as Module:Su except val defaults to align=right.
if align == 'l' or align == 'left' then
align = 'left'
elseif align == 'c' or align == 'center' then
align = 'center'
else
align = 'right'
end
return '<span style="display:inline-block;margin-bottom:-0.3em;vertical-align:-0.4em;line-height:1.2em;font-size:85%;text-align:' ..
align .. ';">' .. sup .. '<br />' .. sub .. '</span>'
end
local function range_text(items, unit_table, options)
local fmt = options.fmt
local nend = items.nend or ''
if items.isrepeat or unit_table.isangle then
nend = nend .. unit_table.text
end
local text = ''
for i = 1, #items do
if i % 2 == 0 then
text = text .. items[i]
else
text = text .. delimit(items[i].sign, items[i].clean, fmt) .. nend
end
end
return text
end
local function uncertainty_text(uncertainty, unit_table, options)
local angle, text, need_parens
if unit_table.isangle then
angle = unit_table.text
end
local upper = uncertainty.upper or {}
local lower = uncertainty.lower or {}
local uncU = upper.clean
if uncU then
local fmt = options.fmt
local uncL = lower.clean
if uncL then
uncU = delimit('+', uncU, fmt) .. (upper.errend or '')
uncL = delimit('−', uncL, fmt) .. (lower.errend or '')
if angle then
uncU = uncU .. angle
uncL = uncL .. angle
end
text = (angle or '') ..
'<span style="margin-left:0.3em;">' ..
sup_sub(uncU, uncL, options.align) ..
'</span>'
else
if upper.parens then
text = '(' .. uncU .. ')' -- old template did not delimit
else
text = (angle or '') ..
'<span style="margin-left:0.3em;margin-right:0.15em;">±</span>' ..
delimit('', uncU, fmt)
need_parens = true
end
if uncertainty.errend then
text = text .. uncertainty.errend
end
if angle then
text = text .. angle
end
end
else
if angle then
text = angle
end
end
return text, need_parens
end
local function _main(values, unit_spec, options)
if options.sandbox then
data_module = data_module .. '/sandbox'
convert_module = convert_module .. '/sandbox'
end
local action = options.action
if action then
if action == 'list' then
-- Kludge: am using the align parameter (a=xxx) for type of list.
return list_units(options.align)
end
return valerror('invalid action "' .. action .. '".', options.nocat)
end
local number = values.number or (values.numbers and values.numbers[1]) or {}
local e_10 = options.e or {}
local novalue = (number.value == nil and e_10.clean == nil)
local fmt = options.fmt
local want_sort = true
local sortable = options.sortable
if sortable == 'off' or (sortable == nil and novalue) then
want_sort = false
elseif sortable == 'debug' then
-- Same as sortable = 'on' but the sort key is displayed.
else
sortable = 'on'
end
local sort_value = 1
if want_sort then
sort_value = number.value or 1
if e_10.value and sort_value ~= 0 then
-- The 'if' avoids {{val|0|e=1234}} giving an invalid sort_value due to overflow.
sort_value = sort_value * 10^e_10.value
end
end
local unit_table = makeunit(sort_value, {
u = unit_spec.u,
want_link = unit_spec.want_link,
per = unit_spec.per,
want_per_link = unit_spec.want_per_link,
nospace = novalue,
want_longscale = unit_spec.want_longscale,
sortable = sortable,
})
local sortkey
if unit_table then
if want_sort then
sortkey = unit_table.sortkey
end
else
unit_table = { text = '' }
if want_sort then
sortkey = convert_lookup('dummy', sort_value, nil, nil, nil, { sortable = sortable }).sortspan
end
end
local final_unit = unit_table.isangle and '' or unit_table.text
local e_text, n_text, need_parens
local uncertainty = values.uncertainty
if uncertainty then
if number.clean then
n_text = delimit(number.sign, number.clean, fmt) .. (number.nend or '')
local text
text, need_parens = uncertainty_text(uncertainty, unit_table, options)
if text then
n_text = n_text .. text
end
else
n_text = ''
end
else
if values.numbers.isrepeat then
final_unit = ''
end
n_text = range_text(values.numbers, unit_table, options)
need_parens = true
end
if e_10.clean then
if need_parens then
n_text = '(' .. n_text .. ')'
end
e_text = '10<sup>' .. delimit(e_10.sign, e_10.clean, fmt) .. '</sup>'
if number.clean then
e_text = '<span style="margin-left:0.25em;margin-right:0.15em;">×</span>' .. e_text
end
else
e_text = ''
end
local result =
(sortkey or '') ..
(options.prefix or '') ..
n_text ..
e_text ..
final_unit ..
(options.suffix or '')
if result ~= '' then
result = '<span class="nowrap">' .. result .. '</span>'
end
return result .. (options.warning or '')
end
local function check_parameters(args, has_ranges, nocat)
-- Return warning text for the first problem parameter found, or nothing if ok.
local whitelist = {
a = true,
action = true,
debug = true,
e = true,
['end'] = true,
errend = true,
['+errend'] = true,
['-errend'] = true,
fmt = true,
['long scale'] = true,
long_scale = true,
longscale = true,
nocategory = true,
p = true,
s = true,
sortable = true,
u = true,
ul = true,
up = true,
upl = true,
}
for k, v in pairs(args) do
if type(k) == 'string' and not whitelist[k] then
local warning = string.format(mtext['mt-val-not-supported'], k, v)
return valerror(warning, nocat, true)
end
end
if not has_ranges and args[4] then
return valerror(mtext['mt-ignore-parameter4'], nocat, true)
end
end
local function main(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame, {wrappers = { 'Template:Val' }})
local nocat = args.nocategory
local numbers = {} -- table of number tables, perhaps with range text
local msg = get_args(numbers, args)
if msg then
return valerror(msg, nocat)
end
if args.u and args.ul then
return valerror(mtext['mt-both-u-ul'], nocat)
end
if args.up and args.upl then
return valerror(mtext['mt-both-up-upl'], nocat)
end
local values
if numbers.has_ranges then
-- Multiple values with range separators but no uncertainty.
numbers.nend = args['end']
values = {
numbers = numbers,
}
else
-- A single value with optional uncertainty.
local function setfield(i, dst, src)
local v = args[src]
if v then
if numbers[i] then
numbers[i][dst] = v
else
numbers[i] = { [dst] = v }
end
end
end
setfield(1, 'nend', 'end')
setfield(2, 'errend', '+errend')
setfield(3, 'errend', '-errend')
values = {
number = numbers[1],
uncertainty = {
upper = numbers[2],
lower = numbers[3],
errend = args.errend,
}
}
end
local unit_spec = {
u = args.ul or args.u,
want_link = args.ul ~= nil,
per = args.upl or args.up,
want_per_link = args.upl ~= nil,
want_longscale = (args.longscale or args.long_scale or args['long scale']) == 'on',
}
local options = {
action = args.action,
align = args.a,
e = numbers.e,
fmt = args.fmt,
nocat = nocat,
prefix = args.p,
sandbox = string.find(frame:getTitle(), 'sandbox', 1, true) ~= nil,
sortable = args.sortable or (args.debug == 'yes' and 'debug' or nil),
suffix = args.s,
warning = check_parameters(args, numbers.has_ranges, nocat),
}
return _main(values, unit_spec, options)
end
return { main = main, _main = _main }
899cf01cf6a449e10309108c9de56689e4205d5c
Module:Citation/CS1/Date validation
828
54
123
2022-07-01T17:45:21Z
Canopus >Trappist the monk
0
sync from sandbox;
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local add_prop_cat, is_set, in_array, set_message, substitute, wrap_style; -- imported functions from selected Module:Citation/CS1/Utilities
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration
--[[--------------------------< F I L E - S C O P E D E C L A R A T I O N S >--------------------------------
File-scope variables are declared here
]]
local lang_object = mw.getContentLanguage(); -- used by is_valid_accessdate(), is_valid_year(), date_name_xlate(); TODO: move to ~/Configuration?
local year_limit; -- used by is_valid_year()
--[=[-------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
returns true if:
Wikipedia start date <= accessdate < today + 2 days
Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time)
accessdate is the date provided in |access-date= at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
if today is 2015-01-01T00:00:00 then
adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser
apparently doesn't understand non-English date month names. This function will always return false when the date
contains a non-English month name because good1 is false after the call to lang.formatDate(). To get around that
call this function with YYYY-MM-DD format dates.
]=]
local function is_valid_accessdate (accessdate)
local good1, good2;
local access_ts, tomorrow_ts; -- to hold Unix time stamps representing the dates
good1, access_ts = pcall (lang_object.formatDate, lang_object, 'U', accessdate ); -- convert accessdate value to Unix timestamp
good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand
access_ts = tonumber (access_ts) or lang_object:parseFormattedNumber (access_ts); -- convert to numbers for the comparison;
tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts);
else
return false; -- one or both failed to convert to Unix time stamp
end
if 979516800 <= access_ts and access_ts < tomorrow_ts then -- Wikipedia start date <= accessdate < tomorrow's date
return true;
else
return false; -- accessdate out of range
end
end
--[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------
returns a number according to the month in a date: 1 for January, etc. Capitalization and spelling must be correct.
If not a valid month, returns 0
]]
local function get_month_number (month)
return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or -- look for local names first
cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or -- failing that, look for English names
0; -- not a recognized month name
end
--[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------
returns a number according to the sequence of seasons in a year: 21 for Spring, etc. Capitalization and spelling
must be correct. If not a valid season, returns 0.
21-24 = Spring, Summer, Autumn, Winter, independent of “Hemisphere”
returns 0 when <param> is not |date=
Season numbering is defined by Extended Date/Time Format (EDTF) specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using
numbers 21-41. cs1|2 only supports generic seasons. EDTF does support the distinction between north and south
hemisphere seasons but cs1|2 has no way to make that distinction.
These additional divisions not currently supported:
25-28 = Spring - Northern Hemisphere, Summer- Northern Hemisphere, Autumn - Northern Hemisphere, Winter - Northern Hemisphere
29-32 = Spring – Southern Hemisphere, Summer– Southern Hemisphere, Autumn – Southern Hemisphere, Winter - Southern Hemisphere
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
37-39 = Quadrimester 1, Quadrimester 2, Quadrimester 3 (4 months each)
40-41 = Semestral 1, Semestral-2 (6 months each)
]]
local function get_season_number (season, param)
if 'date' ~= param then
return 0; -- season dates only supported by |date=
end
return cfg.date_names['local'].season[season] or -- look for local names first
cfg.date_names['en'].season[season] or -- failing that, look for English names
0; -- not a recognized season name
end
--[[--------------------------< G E T _ Q U A R T E R _ N U M B E R >------------------------------------------
returns a number according to the sequence of quarters in a year: 33 for first quarter, etc. Capitalization and spelling
must be correct. If not a valid quarter, returns 0.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
returns 0 when <param> is not |date=
Quarter numbering is defined by Extended Date/Time Format (EDTF) specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using
numbers 21-41. cs1|2 only supports generic seasons and quarters.
These additional divisions not currently supported:
37-39 = Quadrimester 1, Quadrimester 2, Quadrimester 3 (4 months each)
40-41 = Semestral 1, Semestral-2 (6 months each)
]]
local function get_quarter_number (quarter, param)
if 'date' ~= param then
return 0; -- quarter dates only supported by |date=
end
quarter = mw.ustring.gsub (quarter, ' +', ' '); -- special case replace multiple space chars with a single space char
return cfg.date_names['local'].quarter[quarter] or -- look for local names first
cfg.date_names['en'].quarter[quarter] or -- failing that, look for English names
0; -- not a recognized quarter name
end
--[[--------------------------< G E T _ P R O P E R _ N A M E _ N U M B E R >----------------------------------
returns a non-zero number if date contains a recognized proper-name. Capitalization and spelling must be correct.
returns 0 when <param> is not |date=
]]
local function get_proper_name_number (name, param)
if 'date' ~= param then
return 0; -- proper-name dates only supported by |date=
end
return cfg.date_names['local'].named[name] or -- look for local names dates first
cfg.date_names['en'].named[name] or -- failing that, look for English names
0; -- not a recognized named date
end
--[[--------------------------< G E T _ E L E M E N T _ N U M B E R <------------------------------------------
returns true if month or season or quarter or proper name is valid (properly spelled, capitalized, abbreviated)
]]
local function get_element_number (element, param)
local num;
local funcs = {get_month_number, get_season_number, get_quarter_number, get_proper_name_number}; -- list of functions to execute in order
for _, func in ipairs (funcs) do -- spin through the function list
num = func (element, param); -- call the function and get the returned number
if 0 ~= num then -- non-zero when valid month season quarter
return num; -- return that number
end
end
return nil; -- not valid
end
--[[--------------------------< I S _ V A L I D _ Y E A R >----------------------------------------------------
Function gets current year from the server and compares it to year from a citation parameter. Years more than one
year in the future are not acceptable.
Special case for |pmc-embargo-date=: years more than two years in the future are not acceptable
]]
local function is_valid_year (year, param)
if not is_set (year_limit) then
year_limit = tonumber(os.date("%Y"))+1; -- global variable so we only have to fetch it once
end
year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to number for the comparison;
if 'pmc-embargo-date' == param then -- special case for |pmc-embargo-date=
return year and (year <= tonumber(os.date("%Y"))+2) or false; -- years more than two years in the future are not accepted
end
return year and (year <= year_limit) or false;
end
--[[--------------------------< I S _ V A L I D _ D A T E >----------------------------------------------------
Returns true if day is less than or equal to the number of days in month and year is no farther into the future
than next year; else returns false.
Assumes Julian calendar prior to year 1582 and Gregorian calendar thereafter. Accounts for Julian calendar leap
years before 1582 and Gregorian leap years after 1582. Where the two calendars overlap (1582 to approximately
1923) dates are assumed to be Gregorian.
]]
local function is_valid_date (year, month, day, param)
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
local month_length;
if not is_valid_year (year, param) then -- no farther into the future than next year except |pmc-embargo-date= no more than two years in the future
return false;
end
month = tonumber (month); -- required for YYYY-MM-DD dates
if (2 == month) then -- if February
month_length = 28; -- then 28 days unless
if 1582 > tonumber(year) then -- Julian calendar
if 0 == (year%4) then -- is a leap year?
month_length = 29; -- if leap year then 29 days in February
end
else -- Gregorian calendar
if (0 == (year%4) and (0 ~= (year%100) or 0 == (year%400))) then -- is a leap year?
month_length = 29; -- if leap year then 29 days in February
end
end
else
month_length = days_in_month[month];
end
if tonumber (day) > month_length then
return false;
end
return true;
end
--[[--------------------------< I S _ V A L I D _ M O N T H _ R A N G E _ S T Y L E >--------------------------
Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August.
This function looks in cfg.date_names{} to see if both month names are listed in the long subtable or both are
listed in the short subtable. When both have the same style (both are listed in the same table), returns true; false else
]]
local function is_valid_month_range_style (month1, month2)
if (cfg.date_names.en.long[month1] and cfg.date_names.en.long[month2]) or -- are both English names listed in the long subtable?
(cfg.date_names.en.short[month1] and cfg.date_names.en.short[month2]) or -- are both English names listed in the short subtable?
(cfg.date_names['local'].long[month1] and cfg.date_names['local'].long[month2]) or -- are both local names listed in the long subtable?
(cfg.date_names['local'].short[month1] and cfg.date_names['local'].short[month2]) then -- are both local names listed in the short subtable?
return true;
end
return false; -- names are mixed
end
--[[--------------------------< I S _ V A L I D _ M O N T H _ S E A S O N _ R A N G E >------------------------
Check a pair of months or seasons to see if both are valid members of a month or season pair.
Month pairs are expected to be left to right, earliest to latest in time.
All season ranges are accepted as valid because there are publishers out there who have published a Summer–Spring YYYY issue, hence treat as ok
]]
local function is_valid_month_season_range(range_start, range_end, param)
local range_start_number = get_month_number (range_start);
local range_end_number;
if 0 == range_start_number then -- is this a month range?
range_start_number = get_season_number (range_start, param); -- not a month; is it a season? get start season number
range_end_number = get_season_number (range_end, param); -- get end season number
if (0 ~= range_start_number) and (0 ~= range_end_number) and (range_start_number ~= range_end_number) then
return true; -- any season pairing is accepted except when both are the same
end
return false; -- range_start and/or range_end is not a season
end
-- here when range_start is a month
range_end_number = get_month_number (range_end); -- get end month number
if range_start_number < range_end_number and -- range_start is a month; does range_start precede range_end?
is_valid_month_range_style (range_start, range_end) then -- do months have the same style?
return true; -- proper order and same style
end
return false; -- range_start month number is greater than or equal to range end number; or range end isn't a month
end
--[[--------------------------< M A K E _ C O I N S _ D A T E >------------------------------------------------
This function receives a table of date parts for one or two dates and an empty table reference declared in
Module:Citation/CS1. The function is called only for |date= parameters and only if the |date=<value> is
determined to be a valid date format. The question of what to do with invalid date formats is not answered here.
The date parts in the input table are converted to an ISO 8601 conforming date string:
single whole dates: yyyy-mm-dd
month and year dates: yyyy-mm
year dates: yyyy
ranges: yyyy-mm-dd/yyyy-mm-dd
yyyy-mm/yyyy-mm
yyyy/yyyy
Dates in the Julian calendar are reduced to year or year/year so that we don't have to do calendar conversion from
Julian to Proleptic Gregorian.
The input table has:
year, year2 – always present; if before 1582, ignore months and days if present
month, month2 – 0 if not provided, 1-12 for months, 21-24 for seasons; 99 Christmas
day, day2 – 0 if not provided, 1-31 for days
the output table receives:
rftdate: an ISO 8601 formatted date
rftchron: a free-form version of the date, usually without year which is in rftdate (season ranges and proper-name dates)
rftssn: one of four season keywords: winter, spring, summer, fall (lowercase)
rftquarter: one of four values: 1, 2, 3, 4
]]
local function make_COinS_date (input, tCOinS_date)
local date; -- one date or first date in a range
local date2 = ''; -- end of range date
-- start temporary Julian / Gregorian calendar uncertainty detection
local year = tonumber(input.year); -- this temporary code to determine the extent of sources dated to the Julian/Gregorian
local month = tonumber(input.month); -- interstice 1 October 1582 – 1 January 1926
local day = tonumber (input.day);
if (0 ~= day) and -- day must have a value for this to be a whole date
(((1582 == year) and (10 <= month) and (12 >= month)) or -- any whole 1582 date from 1 October to 31 December or
((1926 == year) and (1 == month) and (1 == input.day)) or -- 1 January 1926 or
((1582 < year) and (1925 >= year))) then -- any date 1 January 1583 – 31 December 1925
tCOinS_date.inter_cal_cat = true; -- set category flag true
end
-- end temporary Julian / Gregorian calendar uncertainty detection
if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only
date = input.year;
if 0 ~= input.year2 and input.year ~= input.year2 then -- if a range, only the second year portion when not the same as range start year
date = string.format ('%.4d/%.4d', tonumber(input.year), tonumber(input.year2)) -- assemble the date range
end
if 20 < tonumber(input.month) then -- if season or proper-name date
local season = {[24] = 'winter', [21] = 'spring', [22] = 'summer', [23] = 'fall', [33] = '1', [34] = '2', [35] = '3', [36] = '4', [98] = 'Easter', [99] = 'Christmas'}; -- seasons lowercase, no autumn; proper-names use title case
if 0 == input.month2 then -- single season date
if 40 < tonumber(input.month) then
tCOinS_date.rftchron = season[input.month]; -- proper-name dates
elseif 30 < tonumber(input.month) then
tCOinS_date.rftquarter = season[input.month]; -- quarters
else
tCOinS_date.rftssn = season[input.month]; -- seasons
end
else -- season range with a second season specified
if input.year ~= input.year2 then -- season year – season year range or season year–year
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
if 0~= input.month2 then
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2);
end
else -- season–season year range
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
tCOinS_date.rftchron = season[input.month] .. '–' .. season[input.month2]; -- season–season year range
end
end
end
tCOinS_date.rftdate = date;
return; -- done
end
if 0 ~= input.day then
date = string.format ('%s-%.2d-%.2d', input.year, tonumber(input.month), tonumber(input.day)); -- whole date
elseif 0 ~= input.month then
date = string.format ('%s-%.2d', input.year, tonumber(input.month)); -- year and month
else
date = string.format ('%s', input.year); -- just year
end
if 0 ~= input.year2 then
if 0 ~= input.day2 then
date2 = string.format ('/%s-%.2d-%.2d', input.year2, tonumber(input.month2), tonumber(input.day2)); -- whole date
elseif 0 ~= input.month2 then
date2 = string.format ('/%s-%.2d', input.year2, tonumber(input.month2)); -- year and month
else
date2 = string.format ('/%s', input.year2); -- just year
end
end
tCOinS_date.rftdate = date .. date2; -- date2 has the '/' separator
return;
end
--[[--------------------------< P A T T E R N S >--------------------------------------------------------------
this is the list of patterns for date formats that this module recognizes. Approximately the first half of these
patterns represent formats that might be reformatted into another format. Those that might be reformatted have
'indicator' letters that identify the content of the matching capture: 'd' (day), 'm' (month), 'a' (anchor year),
'y' (year); second day, month, year have a '2' suffix.
These patterns are used for both date validation and for reformatting. This table should not be moved to ~/Configuration
because changes to this table require changes to check_date() and to reformatter() and reformat_date()
]]
local patterns = {
-- year-initial numerical year-month-day
['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'},
-- month-initial: month day, year
['Mdy'] = {'^(%D-) +([1-9]%d?), +((%d%d%d%d?)%a?)$', 'm', 'd', 'a', 'y'},
-- month-initial day range: month day–day, year; days are separated by endash
['Md-dy'] = {'^(%D-) +([1-9]%d?)[%-–]([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'd2', 'a', 'y'},
-- day-initial: day month year
['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'},
-- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed; not supported at en.wiki
-- ['yMd'] = {'^((%d%d%d%d?)%a?) +(%D-) +(%d%d?)$', 'a', 'y', 'm', 'd'},
-- day-range-initial: day–day month year; days are separated by endash
['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'},
-- day initial month-day-range: day month - day month year; uses spaced endash
['dM-dMy'] = {'^([1-9]%d?) +(%D-) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'd2', 'm2', 'a', 'y'},
-- month initial month-day-range: month day – month day, year; uses spaced endash
['Md-Mdy'] = {'^(%D-) +([1-9]%d?) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$','m', 'd', 'm2', 'd2', 'a', 'y'},
-- day initial month-day-year-range: day month year - day month year; uses spaced endash
['dMy-dMy'] = {'^([1-9]%d?) +(%D-) +(%d%d%d%d) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'y', 'd2', 'm2', 'a', 'y2'},
-- month initial month-day-year-range: month day, year – month day, year; uses spaced endash
['Mdy-Mdy'] = {'^(%D-) +([1-9]%d?), +(%d%d%d%d) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'y', 'm2', 'd2', 'a', 'y2'},
-- these date formats cannot be converted, per se, but month name can be rendered short or long
-- month/season year - month/season year; separated by spaced endash
['My-My'] = {'^(%D-) +(%d%d%d%d) +[%-–] +(%D-) +((%d%d%d%d)%a?)$', 'm', 'y', 'm2', 'a', 'y2'},
-- month/season range year; months separated by endash
['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'},
-- month/season year or proper-name year; quarter year when First Quarter YYYY etc.
['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, -- this way because endash is a member of %D; %D- will match January–March 2019 when it shouldn't
-- these date formats cannot be converted
['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash
['Sy-y'] = {'^(%D-) +(%d%d%d%d)[%-–]((%d%d%d%d)%a?)$'}, -- special case Winter/Summer year-year; year separated with unspaced endash
['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- year range: YYYY–YY; separated by unspaced endash
['y'] = {'^((%d%d%d%d?)%a?)$'}, -- year; here accept either YYY or YYYY
}
--[[--------------------------< I S _ V A L I D _ E M B A R G O _ D A T E >------------------------------------
returns true and date value if that value has proper dmy, mdy, ymd format.
returns false and 9999 (embargoed forever) when date value is not proper format; assumes that when |pmc-embargo-date= is
set, the editor intended to embargo a PMC but |pmc-embargo-date= does not hold a single date.
]]
local function is_valid_embargo_date (v)
if v:match (patterns['ymd'][1]) or -- ymd
v:match (patterns['Mdy'][1]) or -- dmy
v:match (patterns['dMy'][1]) then -- mdy
return true, v;
end
return false, '9999'; -- if here not good date so return false and set embargo date to long time in future
end
--[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------
Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only
allowed range separator is endash. Additionally, check the date to see that it is a real date: no 31 in 30-day
months; no 29 February when not a leap year. Months, both long-form and three character abbreviations, and seasons
must be spelled correctly. Future years beyond next year are not allowed.
If the date fails the format tests, this function returns false and does not return values for anchor_year and
COinS_date. When this happens, the date parameter is (DEBUG: not?) used in the COinS metadata and the CITEREF identifier gets
its year from the year parameter if present otherwise CITEREF does not get a date value.
Inputs:
date_string - date string from date-holding parameters (date, year, publication-date, access-date, pmc-embargo-date, archive-date, lay-date)
Returns:
false if date string is not a real date; else
true, anchor_year, COinS_date
anchor_year can be used in CITEREF anchors
COinS_date is ISO 8601 format date; see make_COInS_date()
]]
local function check_date (date_string, param, tCOinS_date)
local year; -- assume that year2, months, and days are not used;
local year2 = 0; -- second year in a year range
local month = 0;
local month2 = 0; -- second month in a month range
local day = 0;
local day2 = 0; -- second day in a day range
local anchor_year;
local coins_date;
if date_string:match (patterns['ymd'][1]) then -- year-initial numerical year month day format
year, month, day = date_string:match (patterns['ymd'][1]);
if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar
anchor_year = year;
elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year
month, day, anchor_year, year = mw.ustring.match(date_string, patterns['Mdy'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
elseif mw.ustring.match(date_string, patterns['Md-dy'][1]) then -- month-initial day range: month day–day, year; days are separated by endash
month, day, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-dy'][1]);
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same;
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
month2=month; -- for metadata
year2 = year;
elseif mw.ustring.match(date_string, patterns['dMy'][1]) then -- day-initial: day month year
day, month, anchor_year, year = mw.ustring.match(date_string, patterns['dMy'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
--[[ NOT supported at en.wiki
elseif mw.ustring.match(date_string, patterns['yMd'][1]) then -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed
anchor_year, year, month, day = mw.ustring.match(date_string, patterns['yMd'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
-- end NOT supported at en.wiki ]]
elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash
day, day2, month, anchor_year, year = mw.ustring.match(date_string, patterns['d-dMy'][1]);
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same;
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
month2 = month; -- for metadata
year2 = year;
elseif mw.ustring.match(date_string, patterns['dM-dMy'][1]) then -- day initial month-day-range: day month - day month year; uses spaced endash
day, month, day2, month2, anchor_year, year = mw.ustring.match(date_string, patterns['dM-dMy'][1]);
if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later;
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
year2 = year;
elseif mw.ustring.match(date_string, patterns['Md-Mdy'][1]) then -- month initial month-day-range: month day – month day, year; uses spaced endash
month, day, month2, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-Mdy'][1]);
if (not is_valid_month_season_range(month, month2, param)) or not is_valid_year(year) then return false; end
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
year2 = year;
elseif mw.ustring.match(date_string, patterns['dMy-dMy'][1]) then -- day initial month-day-year-range: day month year - day month year; uses spaced endash
day, month, year, day2, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['dMy-dMy'][1]);
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
if 0 == month or 0 == month2 then return false; end -- both must be valid
elseif mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]) then -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash
month, day, year, month2, day2, anchor_year, year2 = mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]);
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style
month = get_month_number (month); -- for metadata
month2 = get_month_number(month2);
if 0 == month or 0 == month2 then return false; end -- both must be valid
elseif mw.ustring.match(date_string, patterns['Sy4-y2'][1]) then -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash
local century;
month, year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy4-y2'][1]);
if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
year2 = century..year2; -- add the century to year2 for comparisons
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
month = get_season_number(month, param);
elseif mw.ustring.match(date_string, patterns['Sy-y'][1]) then -- special case Winter/Summer year-year; year separated with unspaced endash
month, year, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy-y'][1]);
month = get_season_number (month, param); -- <month> can only be winter or summer; also for metadata
if (month ~= cfg.date_names['en'].season['Winter']) and (month ~= cfg.date_names['en'].season['Summer']) then
return false; -- not Summer or Winter; abandon
end
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['My-My'][1]) then -- month/season year - month/season year; separated by spaced endash
month, year, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['My-My'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
if 0 ~= get_month_number(month) and 0 ~= get_month_number(month2) and is_valid_month_range_style(month, month2) then -- both must be month year, same month style
month = get_month_number(month);
month2 = get_month_number(month2);
elseif 0 ~= get_season_number(month, param) and 0 ~= get_season_number(month2, param) then -- both must be season year, not mixed
month = get_season_number(month, param);
month2 = get_season_number(month2, param);
else
return false;
end
elseif mw.ustring.match(date_string, patterns['M-My'][1]) then -- month/season range year; months separated by endash
month, month2, anchor_year, year = mw.ustring.match(date_string, patterns['M-My'][1]);
if (not is_valid_month_season_range(month, month2, param)) or (not is_valid_year(year)) then return false; end
if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season
month = get_month_number(month);
month2 = get_month_number(month2);
if 0 == month or 0 == month2 then return false; end
else
month = get_season_number(month, param);
month2 = get_season_number(month2, param);
end
year2 = year;
elseif mw.ustring.match(date_string, patterns['My'][1]) then -- month/season/quarter/proper-name year
month, anchor_year, year = mw.ustring.match(date_string, patterns['My'][1]);
if not is_valid_year(year) then return false; end
month = get_element_number(month, param); -- get month season quarter proper-name number or nil
if not month then return false; end -- not valid whatever it is
elseif mw.ustring.match(date_string, patterns['y-y'][1]) then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
year, anchor_year, year2 = mw.ustring.match(date_string, patterns['y-y'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['y4-y2'][1]) then -- Year range: YYYY–YY; separated by unspaced endash
local century;
year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['y4-y2'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
if in_array (param, {'date', 'publication-date', 'year'}) then
add_prop_cat ('year-range-abbreviated');
end
if 13 > tonumber(year2) then return false; end -- don't allow 2003-05 which might be May 2003
year2 = century .. year2; -- add the century to year2 for comparisons
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['y'][1]) then -- year; here accept either YYY or YYYY
anchor_year, year = mw.ustring.match(date_string, patterns['y'][1]);
if false == is_valid_year(year) then
return false;
end
else
return false; -- date format not one of the MOS:DATE approved formats
end
if 'access-date' == param then -- test accessdate here because we have numerical date parts
if 0 ~= year and 0 ~= month and 0 ~= day and -- all parts of a single date required
0 == year2 and 0 == month2 and 0 == day2 then -- none of these; accessdate must not be a range
if not is_valid_accessdate(year .. '-' .. month .. '-' .. day) then
return false; -- return false when accessdate out of bounds
end
else
return false; -- return false when accessdate is a range of two dates
end
end
local result=true; -- check whole dates for validity; assume true because not all dates will go through this test
if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then -- YMD (simple whole date)
result = is_valid_date (year, month, day, param); -- <param> for |pmc-embargo-date=
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then -- YMD-d (day range)
result = is_valid_date (year, month, day);
result = result and is_valid_date (year, month, day2);
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-md (day month range)
result = is_valid_date (year, month, day);
result = result and is_valid_date (year, month2, day2);
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 ~= year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-ymd (day month year range)
result = is_valid_date(year, month, day);
result = result and is_valid_date(year2, month2, day2);
end
if false == result then return false; end
if nil ~= tCOinS_date then -- this table only passed into this function when testing |date= parameter values
make_COinS_date ({year = year, month = month, day = day, year2 = year2, month2 = month2, day2 = day2}, tCOinS_date); -- make an ISO 8601 date string for COinS
end
return true, anchor_year; -- format is good and date string represents a real date
end
--[[--------------------------< D A T E S >--------------------------------------------------------------------
Cycle the date-holding parameters in passed table date_parameters_list through check_date() to check compliance with MOS:DATE. For all valid dates, check_date() returns
true. The |date= parameter test is unique, it is the only date holding parameter from which values for anchor_year (used in CITEREF identifiers) and COinS_date (used in
the COinS metadata) are derived. The |date= parameter is the only date-holding parameter that is allowed to contain the no-date keywords "n.d." or "nd" (without quotes).
Unlike most error messages created in this module, only one error message is created by this function. Because all of the date holding parameters are processed serially,
parameters with errors are added to the <error_list> sequence table as the dates are tested.
]]
local function dates(date_parameters_list, tCOinS_date, error_list)
local anchor_year; -- will return as nil if the date being tested is not |date=
local COinS_date; -- will return as nil if the date being tested is not |date=
local embargo_date; -- if embargo date is a good dmy, mdy, ymd date then holds original value else reset to 9999
local good_date = false;
for k, v in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(v.val) then -- if the parameter has a value
v.val = mw.ustring.gsub(v.val, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9
if v.val:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year=
local year = v.val:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested
if 'date' == k then
anchor_year, COinS_date = v.val:match("((c%. [1-9]%d%d%d?)%a?)"); -- anchor year and COinS_date only from |date= parameter
good_date = is_valid_year(year);
elseif 'year' == k then
good_date = is_valid_year(year);
end
elseif 'date' == k then -- if the parameter is |date=
if v.val:match("^n%.d%.%a?$") then -- ToDo: I18N -- if |date=n.d. with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((n%.d%.)%a?)"); -- ToDo: I18N -- "n.d."; no error when date parameter is set to no date
elseif v.val:match("^nd%a?$") then -- ToDo: I18N -- if |date=nd with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((nd)%a?)"); -- ToDo: I18N -- "nd"; no error when date parameter is set to no date
else
good_date, anchor_year, COinS_date = check_date (v.val, k, tCOinS_date); -- go test the date
end
elseif 'year' == k then -- if the parameter is |year= it should hold only a year value
if v.val:match("^[1-9]%d%d%d?%a?$") then -- if |year = 3 or 4 digits only with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((%d+)%a?)");
end
elseif 'pmc-embargo-date' == k then -- if the parameter is |pmc-embargo-date=
good_date = check_date (v.val, k); -- go test the date
if true == good_date then -- if the date is a valid date
good_date, embargo_date = is_valid_embargo_date (v.val); -- is |pmc-embargo-date= date a single dmy, mdy, or ymd formatted date? yes: returns embargo date; no: returns 9999
end
else -- any other date-holding parameter
good_date = check_date (v.val, k); -- go test the date
end
if false == good_date then -- assemble one error message so we don't add the tracking category multiple times
table.insert (error_list, wrap_style ('parameter', v.name)); -- make parameter name suitable for error message list
end
end
end
return anchor_year, embargo_date; -- and done
end
--[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------
Compare the value provided in |year= with the year value(s) provided in |date=. This function sets a local numeric value:
0 - year value does not match the year value in date
1 - (default) year value matches the year value in date or one of the year values when date contains two years
2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx)
the numeric value in <result> determines the 'output' if any from this function:
0 – adds error message to error_list sequence table
1 – adds maint cat
2 – does nothing
]]
local function year_date_check (year_string, year_origin, date_string, date_origin, error_list)
local year;
local date1;
local date2;
local result = 1; -- result of the test; assume that the test passes
year = year_string:match ('(%d%d%d%d?)');
if date_string:match ('%d%d%d%d%-%d%d%-%d%d') and year_string:match ('%d%d%d%d%a') then --special case where both date and year are required YYYY-MM-DD and YYYYx
date1 = date_string:match ('(%d%d%d%d)');
year = year_string:match ('(%d%d%d%d)');
if year ~= date1 then
result = 0; -- years don't match
else
result = 2; -- years match; but because disambiguated, don't add to maint cat
end
elseif date_string:match ("%d%d%d%d?.-%d%d%d%d?") then -- any of the standard range formats of date with two three- or four-digit years
date1, date2 = date_string:match ("(%d%d%d%d?).-(%d%d%d%d?)");
if year ~= date1 and year ~= date2 then
result = 0;
end
elseif mw.ustring.match(date_string, "%d%d%d%d[%-–]%d%d") then -- YYYY-YY date ranges
local century;
date1, century, date2 = mw.ustring.match(date_string, "((%d%d)%d%d)[%-–]+(%d%d)");
date2 = century..date2; -- convert YY to YYYY
if year ~= date1 and year ~= date2 then
result = 0;
end
elseif date_string:match ("%d%d%d%d?") then -- any of the standard formats of date with one year
date1 = date_string:match ("(%d%d%d%d?)");
if year ~= date1 then
result = 0;
end
else -- should never get here; this function called only when no other date errors
result = 0; -- no recognizable year in date
end
if 0 == result then -- year / date mismatch
table.insert (error_list, substitute (cfg.messages['mismatch'], {year_origin, date_origin})); -- add error message to error_list sequence table
elseif 1 == result then -- redundant year / date
set_message ('maint_date_year'); -- add a maint cat
end
end
--[[--------------------------< R E F O R M A T T E R >--------------------------------------------------------
reformat 'date' into new format specified by format_param if pattern_idx (the current format of 'date') can be
reformatted. Does the grunt work for reformat_dates().
The table re_formats maps pattern_idx (current format) and format_param (desired format) to a table that holds:
format string used by string.format()
identifier letters ('d', 'm', 'y', 'd2', 'm2', 'y2') that serve as indexes into a table t{} that holds captures
from mw.ustring.match() for the various date parts specified by patterns[pattern_idx][1]
Items in patterns{} have the general form:
['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'}, where:
['ymd'] is pattern_idx
patterns['ymd'][1] is the match pattern with captures for mw.ustring.match()
patterns['ymd'][2] is an indicator letter identifying the content of the first capture
patterns['ymd'][3] ... the second capture etc.
when a pattern matches a date, the captures are loaded into table t{} in capture order using the idemtifier
characters as indexes into t{} For the above, a ymd date is in t{} as:
t.y = first capture (year), t.m = second capture (month), t.d = third capture (day)
To reformat, this function is called with the pattern_idx that matches the current format of the date and with
format_param set to the desired format. This function loads table t{} as described and then calls string.format()
with the format string specified by re_format[pattern_idx][format_param][1] using values taken from t{} according
to the capture identifier letters specified by patterns[pattern_idx][format_param][n] where n is 2..
]]
local re_formats = {
['ymd'] = { -- date format is ymd; reformat to:
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['Mdy'] = { -- date format is Mdy; reformat to:
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- for long/short reformatting
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['dMy'] = { -- date format is dMy; reformat to:
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['Md-dy'] = { -- date format is Md-dy; reformat to:
['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- for long/short reformatting
['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- |df=dmy -> d-dMy
},
['d-dMy'] = { -- date format is d-d>y; reformat to:
['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- |df=mdy -> Md-dy
},
['dM-dMy'] = { -- date format is dM-dMy; reformat to:
['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- |df=mdy -> Md-Mdy
},
['Md-Mdy'] = { -- date format is Md-Mdy; reformat to:
['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- for long/short reformatting
['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- |df=dmy -> dM-dMy
},
['dMy-dMy'] = { -- date format is dMy-dMy; reformat to:
['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- for long/short reformatting
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- |df=mdy -> Mdy-Mdy
},
['Mdy-Mdy'] = { -- date format is Mdy-Mdy; reformat to:
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- for long/short reformatting
['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- |df=dmy -> dMy-dMy
},
['My-My'] = { -- these for long/short reformatting
['any'] = {'%s %s – %s %s', 'm', 'y', 'm2', 'y2'}, -- dmy/mdy agnostic
},
['M-My'] = { -- these for long/short reformatting
['any'] = {'%s–%s %s', 'm', 'm2', 'y'}, -- dmy/mdy agnostic
},
['My'] = { -- these for long/short reformatting
['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic
},
-- ['yMd'] = { -- not supported at en.wiki
-- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
-- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
-- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- },
}
local function reformatter (date, pattern_idx, format_param, mon_len)
if not in_array (pattern_idx, {'ymd', 'Mdy', 'Md-dy', 'dMy', 'yMd', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then
return; -- not in this set of date format patterns then not a reformattable date
end
if 'ymd' == format_param and in_array (pattern_idx, {'ymd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then
return; -- ymd date ranges not supported at en.wiki; no point in reformatting ymd to ymd
end
if in_array (pattern_idx, {'My', 'M-My', 'My-My'}) then -- these are not dmy/mdy so can't be 'reformatted' into either
format_param = 'any'; -- so format-agnostic
end
-- yMd is not supported at en.wiki; when yMd is supported at your wiki, uncomment the next line
-- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- these formats not convertable; yMd not supported at en.wiki
if 'yMd' == format_param then -- yMd not supported at en.wiki; when yMd is supported at your wiki, remove or comment-out this line
return; -- not a reformattable date
end
local c1, c2, c3, c4, c5, c6, c7; -- these hold the captures specified in patterns[pattern_idx][1]
c1, c2, c3, c4, c5, c6, c7 = mw.ustring.match (date, patterns[pattern_idx][1]); -- get the captures
local t = { -- table that holds k/v pairs of date parts from the captures and patterns[pattern_idx][2..]
[patterns[pattern_idx][2]] = c1; -- at minimum there is always one capture with a matching indicator letter
[patterns[pattern_idx][3] or 'x'] = c2; -- patterns can have a variable number of captures; each capture requires an indicator letter;
[patterns[pattern_idx][4] or 'x'] = c3; -- where there is no capture, there is no indicator letter so n in patterns[pattern_idx][n] will be nil;
[patterns[pattern_idx][5] or 'x'] = c4; -- the 'x' here spoofs an indicator letter to prevent 'table index is nil' error
[patterns[pattern_idx][6] or 'x'] = c5;
[patterns[pattern_idx][7] or 'x'] = c6;
[patterns[pattern_idx][8] or 'x'] = c7;
};
if t.a then -- if this date has an anchor year capture (all convertable date formats except ymd)
if t.y2 then -- for year range date formats
t.y2 = t.a; -- use the anchor year capture when reassembling the date
else -- here for single date formats (except ymd)
t.y = t.a; -- use the anchor year capture when reassembling the date
end
end
if tonumber(t.m) then -- if raw month is a number (converting from ymd)
if 's' == mon_len then -- if we are to use abbreviated month names
t.m = cfg.date_names['inv_local_short'][tonumber(t.m)]; -- convert it to a month name
else
t.m = cfg.date_names['inv_local_long'][tonumber(t.m)]; -- convert it to a month name
end
t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present
elseif 'ymd' == format_param then -- when converting to ymd
t.y = t.y:gsub ('%a', ''); -- strip CITREF disambiguator if present; anchor year already known so process can proceed; TODO: maint message?
if 1582 > tonumber (t.y) then -- ymd format dates not allowed before 1582
return;
end
t.m = string.format ('%02d', get_month_number (t.m)); -- make sure that month and day are two digits
t.d = string.format ('%02d', t.d);
elseif mon_len then -- if mon_len is set to either 'short' or 'long'
for _, mon in ipairs ({'m', 'm2'}) do -- because there can be two month names, check both
if t[mon] then
t[mon] = get_month_number (t[mon]); -- get the month number for this month (is length agnostic)
if 0 == t[mon] then return; end -- seasons and named dates can't be converted
t[mon] = (('s' == mon_len) and cfg.date_names['inv_local_short'][t[mon]]) or cfg.date_names['inv_local_long'][t[mon]]; -- fetch month name according to length
end
end
end
local new_date = string.format (re_formats[pattern_idx][format_param][1], -- format string
t[re_formats[pattern_idx][format_param][2]], -- named captures from t{}
t[re_formats[pattern_idx][format_param][3]],
t[re_formats[pattern_idx][format_param][4]],
t[re_formats[pattern_idx][format_param][5]],
t[re_formats[pattern_idx][format_param][6]],
t[re_formats[pattern_idx][format_param][7]],
t[re_formats[pattern_idx][format_param][8]]
);
return new_date;
end
--[[-------------------------< R E F O R M A T _ D A T E S >--------------------------------------------------
Reformats existing dates into the format specified by format.
format is one of several manual keywords: dmy, dmy-all, mdy, mdy-all, ymd, ymd-all. The -all version includes
access- and archive-dates; otherwise these dates are not reformatted.
This function allows automatic date formatting. In ~/Configuration, the article source is searched for one of
the {{use xxx dates}} templates. If found, xxx becomes the global date format as xxx-all. If |cs1-dates= in
{{use xxx dates}} has legitimate value then that value determines how cs1|2 dates will be rendered. Legitimate
values for |cs1-dates= are:
l - all dates are rendered with long month names
ls - publication dates use long month names; access-/archive-dates use abbreviated month names
ly - publication dates use long month names; access-/archive-dates rendered in ymd format
s - all dates are rendered with abbreviated (short) month names
sy - publication dates use abbreviated month names; access-/archive-dates rendered in ymd format
y - all dates are rendered in ymd format
the format argument for automatic date formatting will be the format specified by {{use xxx dates}} with the
value supplied by |cs1-dates so one of: xxx-l, xxx-ls, xxx-ly, xxx-s, xxx-sy, xxx-y, or simply xxx (|cs1-dates=
empty, omitted, or invalid) where xxx shall be either of dmy or mdy.
dates are extracted from date_parameters_list, reformatted (if appropriate), and then written back into the
list in the new format. Dates in date_parameters_list are presumed here to be valid (no errors). This function
returns true when a date has been reformatted, false else. Actual reformatting is done by reformatter().
]]
local function reformat_dates (date_parameters_list, format)
local all = false; -- set to false to skip access- and archive-dates
local len_p = 'l'; -- default publication date length shall be long
local len_a = 'l'; -- default access-/archive-date length shall be long
local result = false;
local new_date;
if format:match('%a+%-all') then -- manual df keyword; auto df keyword when length not specified in {{use xxx dates}};
format = format:match('(%a+)%-all'); -- extract the format
all = true; -- all dates are long format dates because this keyword doesn't specify length
elseif format:match('%a+%-[lsy][sy]?') then -- auto df keywords; internal only
all = true; -- auto df applies to all dates; use length specified by capture len_p for all dates
format, len_p, len_a = format:match('(%a+)%-([lsy])([sy]?)'); -- extract the format and length keywords
if 'y' == len_p then -- because allowed by MOS:DATEUNIFY (sort of) range dates and My dates not reformatted
format = 'ymd'; -- override {{use xxx dates}}
elseif (not is_set(len_a)) or (len_p == len_a) then -- no access-/archive-date length specified or same length as publication dates then
len_a = len_p; -- in case len_a not set
end
end -- else only publication dates and they are long
for param_name, param_val in pairs (date_parameters_list) do -- for each date-holding parameter in the list
if is_set (param_val.val) then -- if the parameter has a value
if not (not all and in_array (param_name, {'access-date', 'archive-date'})) then -- skip access- or archive-date unless format is xxx-all; yeah, ugly; TODO: find a better way
for pattern_idx, pattern in pairs (patterns) do
if mw.ustring.match (param_val.val, pattern[1]) then
if all and in_array (param_name, {'access-date', 'archive-date'}) then -- if this date is an access- or archive-date
new_date = reformatter (param_val.val, pattern_idx, (('y' == len_a) and 'ymd') or format, len_a); -- choose ymd or dmy/mdy according to len_a setting
else -- all other dates
new_date = reformatter (param_val.val, pattern_idx, format, len_p);
end
if new_date then -- set when date was reformatted
date_parameters_list[param_name].val = new_date; -- update date in date list
result = true; -- and announce that changes have been made
end
end -- if
end -- for
end -- if
end -- if
end -- for
return result; -- declare boolean result and done
end
--[[--------------------------< D A T E _ H Y P H E N _ T O _ D A S H >----------------------------------------
Loops through the list of date-holding parameters and converts any hyphen to an ndash. Not called if the cs1|2
template has any date errors.
Modifies the date_parameters_list and returns true if hyphens are replaced, else returns false.
]]
local function date_hyphen_to_dash (date_parameters_list)
local result = false;
local n;
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set (param_val.val) and
not mw.ustring.match (param_val.val, patterns.ymd[1]) then -- for those that are not ymd dates (ustring because here digits may not be Western)
param_val.val, n = param_val.val:gsub ('%-', '–'); -- replace any hyphen with ndash
if 0 ~= n then
date_parameters_list[param_name].val = param_val.val; -- update the list
result = true;
end
end
end
return result; -- so we know if any hyphens were replaced
end
--[[-------------------------< D A T E _ N A M E _ X L A T E >------------------------------------------------
Attempts to translate English date names to local-language date names using names supplied by MediaWiki's
date parser function. This is simple name-for-name replacement and may not work for all languages.
if xlat_dig is true, this function will also translate Western (English) digits to the local language's digits.
This will also translate ymd dates.
]]
local function date_name_xlate (date_parameters_list, xlt_dig)
local xlate;
local mode; -- long or short month names
local modified = false;
local date;
local sources_t = {
{cfg.date_names.en.long, cfg.date_names.inv_local_long}, -- for translating long English month names to long local month names
{cfg.date_names.en.short, cfg.date_names.inv_local_short}, -- short month names
{cfg.date_names.en.quarter, cfg.date_names.inv_local_quarter}, -- quarter date names
{cfg.date_names.en.season, cfg.date_names.inv_local_season}, -- season date nam
{cfg.date_names.en.named, cfg.date_names.inv_local_named}, -- named dates
}
local function is_xlateable (month) -- local function to get local date name that replaces existing English-language date name
for _, date_names_t in ipairs (sources_t) do -- for each sequence table in date_names_t
if date_names_t[1][month] then -- if date name is English month (long or short), quarter, season or named and
if date_names_t[2][date_names_t[1][month]] then -- if there is a matching local date name
return date_names_t[2][date_names_t[1][month]]; -- return the local date name
end
end
end
end
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(param_val.val) then -- if the parameter has a value
date = param_val.val;
for month in mw.ustring.gmatch (date, '[%a ]+') do -- iterate through all date names in the date (single date or date range)
month = mw.text.trim (month); -- this because quarterly dates contain whitespace
xlate = is_xlateable (month); -- get translate <month>; returns translation or nil
-- if cfg.date_names.en.long[month] then -- long month dates
-- if cfg.date_names.inv_local_long[cfg.date_names.en.long[month]] then
-- xlate = cfg.date_names.inv_local_long[cfg.date_names.en.long[month]];
-- end
---- mode = 'F'; -- English name is long so use long local name
-- elseif cfg.date_names.en.short[month] then -- short month dates
-- if cfg.date_names.inv_local_short[cfg.date_names.en.short[month]] then
-- xlate = cfg.date_names.inv_local_short[cfg.date_names.en.short[month]];
-- end
---- mode = 'M'; -- English name is short so use short local name
-- elseif cfg.date_names.en.quarter[month] then -- quarter dates
-- if cfg.date_names.inv_local_quarter[cfg.date_names.en.quarter[month]] then
-- xlate = cfg.date_names.inv_local_quarter[cfg.date_names.en.quarter[month]];
-- end
-- elseif cfg.date_names.en.season[month] then -- season dates
-- if cfg.date_names.inv_local_season[cfg.date_names.en.season[month]] then
-- xlate = cfg.date_names.inv_local_season[cfg.date_names.en.season[month]];
-- end
-- elseif cfg.date_names.en.named[month] then -- named dates
-- if cfg.date_names.inv_local_named[cfg.date_names.en.named[month]] then
-- xlate = cfg.date_names.inv_local_named[cfg.date_names.en.named[month]];
-- end
-- else
-- xlate=nil; -- not an English month name; could be local language month name
---- mode = nil; -- not an English month name; could be local language month name or an English season name
-- end
if xlate then
-- if mode then -- might be a season
-- xlate = lang_object:formatDate(mode, '1' .. month); -- translate the month name to this local language
date = mw.ustring.gsub (date, month, xlate); -- replace the English with the translation
date_parameters_list[param_name].val = date; -- save the translated date
modified = true;
end
end
if xlt_dig then -- shall we also translate digits?
date = date:gsub ('%d', cfg.date_names.xlate_digits); -- translate digits from Western to 'local digits'
date_parameters_list[param_name].val = date; -- save the translated date
modified = true;
end
end
end
return modified;
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
add_prop_cat = utilities_page_ptr.add_prop_cat ; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
set_message = utilities_page_ptr.set_message;
substitute = utilities_page_ptr.substitute;
wrap_style = utilities_page_ptr.wrap_style;
cfg = cfg_table_ptr; -- import tables from selected Module:Citation/CS1/Configuration
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return { -- return exported functions
dates = dates,
year_date_check = year_date_check,
reformat_dates = reformat_dates,
date_hyphen_to_dash = date_hyphen_to_dash,
date_name_xlate = date_name_xlate,
set_selected_modules = set_selected_modules
}
d0271b200019639fd12f2b6c5e53be0e844e8453
Module:Citation/CS1
828
50
115
2022-07-01T17:45:25Z
Canopus >Trappist the monk
0
sync from sandbox;
Scribunto
text/plain
require ('Module:No globals');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z ={}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- Boolean flag so that the category is added only once
local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local Frame; -- holds the module's frame table
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between
the first and last characters the name may use letters, digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
if not domain:match ('^[%w]') then -- first character must be letter or digit
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs ({'cash', 'company', 'today', 'org'}) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local err_msg = '';
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]);
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local cap = '';
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_code_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param>
utilities.set_message ('err_trans_missing_title', {chapter_source});
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = capture .. ' ' .. char_name;
else
err_msg = char_name .. ' ' .. 'character';
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded.
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local args, list, v = args, cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
tbl = rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap = '';
local cap2 = '';
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
trim = false;
end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials(first, position)
local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match(first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials, names = {}, {}; -- tables to hold name parts and initials
local i = 1; -- counter for number of initials
names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix
while names[i] do -- loop through the table
if 1 < i and names[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names[i] = names[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names[i]) then -- if a legitimate suffix
table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials, mw.ustring.sub(names[i], 1, 1)); -- insert the initial at end of initials table
end
i = i + 1; -- bump the counter
end
return table.concat(initials) -- Vancouver format does not include spaces.
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. ' ' .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add maint cat when name parameter value does not contain letters. Does not catch
mixed alphanumeric names so |last=A. Green (1922-1987) does not get caught in the
current version of this test but |first=(1888) is caught.
returns nothing
]]
local function name_is_numeric (name, list_name)
if utilities.is_set (name) then
if mw.ustring.match (name, '^[%A]+$') then -- when name does not contain any letters
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
returns nothing
]]
local function name_has_mult_names (name, list_name)
local _, commas, semicolons, nbsps;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if 1 < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value, wiki)
local test_val;
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter (last only)
name_is_numeric (last, list_name); -- check for names that are composed of digits and punctuation
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_is_numeric (first, list_name); -- check for names that are composed of digits and punctuation
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
local result;
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_code_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_code_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_code_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = {}; -- table made from the value assigned to |language=
local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
-- utilities.add_prop_cat ('foreign-lang-source', {name, lang_subtag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
name = ''; -- so we can reuse it
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or 'citation' == cite_class then
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors']; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
]]
local function get_display_names (max, count, list_name, etal, param)
if utilities.is_set (max) then
if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if max >= count then -- if |display-xxxxors= value greater than or equal to number of authors/editors
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive).
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local patterns = 'v' == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns;
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (patterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirstTable = {}
lastfirstTable = mw.text.split(v_name, "%s+")
first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove(lastfirstTable); -- get what should be the initials from the table
end
last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
local err_name;
if 'AuthorList' == list_name then -- figure out which name should be used in error message
err_name = 'author';
else
err_name = 'editor';
end
utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------
returns the concatenation of the formatted volume and issue parameters as a single string; or formatted volume
or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, cite_class, origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
if utilities.is_set (issue) then
return vol .. utilities.substitute (cfg.messages['j-issue'], issue);
end
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
]=]
local function archive_url_check (url, date)
local err_msg = ''; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date; -- return ArchiveURL and ArchiveDate
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date; -- preview mode so return ArchiveURL and ArchiveDate
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
local i
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, args.vauthors, 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |authors=
if 'authors' == A:ORIGIN('Authors') then -- but add a maint cat if the parameter is |authors=
utilities.set_message ('maint_authors'); -- because use of this parameter is discouraged; what to do about the aliases is a TODO:
end
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then
Contribution = Chapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = '';
if utilities.is_set (Periodical) then
Periodical_origin = A:ORIGIN('Periodical'); -- get the name of the periodical parameter
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. ' and ' .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
local ScriptPeriodical = A['ScriptPeriodical'];
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = utilities.hyphen_to_dash (A['Issue']);
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = utilities.hyphen_to_dash (A['Issue']);
end
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
local Page;
local Pages;
local At;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
end
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) then
local i = 0;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if utilities.in_array (this_page.nsText, cfg.uncategorized_namespaces) then
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different
utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together
if PublicationPlace == Place then
Place = ''; -- unset; don't need both if they are the same
end
elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title=
|encyclopedia= and |article= then map |encyclopedia= to |title=
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
if utilities.is_set (Encyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
Encyclopedia = nil; -- unset because not supported by this template
end
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', A:ORIGIN ('Encyclopedia')) .. ' and ' .. utilities.wrap_style ('parameter', Periodical_origin)});
end
if utilities.is_set (Encyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia; allow periodical without encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
end
if utilities.is_set (Periodical) then -- Periodical is set when |encyclopedia= is set
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= to |article= and |encyclopedia= to |title=
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
Title = Periodical;
ChapterFormat = Format;
Periodical = ''; -- redundant so unset
TransTitle = '';
URL = '';
Format = '';
TitleLink = '';
ScriptTitle = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title=
Periodical = ''; -- redundant so unset
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. ' and ' .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
-- CS1/2 mode
local Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], '');
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
-- controls capitalization of certain static text
local use_lowercase = ( sepc == ',' );
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
if utilities.is_set (Chapter) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. ' and ' .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message
end
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map');
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. ' and ' .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
-- legacy: promote PublicationDate to Date if neither Date nor Year are set.
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local PublicationDate = A['PublicationDate'];
local Year = A['Year'];
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promote PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
end
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local LayDate = A['LayDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables error_message, date_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
local date_parameters_list = {
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['lay-date'] = {val = LayDate, name = A:ORIGIN ('LayDate')},
['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
-- start temporary Julian / Gregorian calendar uncertainty categorization
if COinS_date.inter_cal_cat then
utilities.add_prop_cat ('jul-greg-uncertainty');
end
-- end temporary Julian / Gregorian calendar uncertainty categorization
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
LayDate = date_parameters_list['lay-date'].val;
PublicationDate = date_parameters_list['publication-date'].val;
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
local ID_list = {}; -- sequence table of rendered identifiers
local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list) then
if not utilities.is_set (ID_list_coins[config.CitationClass:upper()]) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv= & |citeseerx= required for their templates
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
local QuotePage = A['QuotePage'];
local QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date has correctly formatted date if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron or (not COinS_date.rftdate and Date) or '', -- chron but if not set and invalid date format use Date; keep this last bit?
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal;
local Translators; -- assembled translators name list
local translator_etal;
local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs
t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = {};
interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal;
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
control.maximum , editor_etal = get_display_names (A['DisplayEditors'], #e, 'editors', editor_etal, A:ORIGIN ('DisplayEditors'));
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
control.maximum, interviewer_etal = get_display_names (A['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, A:ORIGIN ('DisplayInterviewers'));
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
control.maximum, translator_etal = get_display_names (A['DisplayTranslators'], #t, 'translators', translator_etal, A:ORIGIN ('DisplayTranslators'));
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
control.maximum, contributor_etal = get_display_names (A['DisplayContributors'], #c, 'contributors', contributor_etal, A:ORIGIN ('DisplayContributors'));
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
control.maximum, author_etal = get_display_names (A['DisplayAuthors'], #a, 'authors', author_etal, A:ORIGIN ('DisplayAuthors'));
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
-- special case for chapter format so no error message or cat when chapter not supported
if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
end
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
utilities.set_message ('err_cite_web_url');
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = '';
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = "";
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
if utilities.is_set (Place) then
Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " ";
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. ' and ' .. utilities.wrap_style ('parameter', 'time')});
end
Position = " " .. Minutes .. " " .. cfg.messages['minutes'];
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cfg.messages['event'];
if sepc ~= '.' then
TimeCaption = TimeCaption:lower();
end
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'];
Agency = utilities.is_set (Agency) and wrap_msg ('agency', {sepc, Agency}) or "";
Volume = format_volume_issue (Volume, Issue, config.CitationClass, Periodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved']
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
local Quote = A['Quote'];
local TransQuote = A['TransQuote'];
local ScriptQuote = A['ScriptQuote'];
if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then
if utilities.is_set (Quote) then
if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
Quote = Quote:sub(2, -2); -- strip them off
end
end
Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags
if utilities.is_set (ScriptQuote) then
Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (TransQuote) then
if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
TransQuote = TransQuote:sub(2, -2); -- strip them off
end
Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote );
end
if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (QuotePage) then
extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not NoPP then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', '';
end
elseif utilities.is_set (QuotePages) then
extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', '';
elseif not NoPP then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', '';
end
end
Quote = quote_prefix .. ": " .. Quote;
else
Quote = sepc .. " " .. Quote;
end
PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
local arch_text;
if not utilities.is_set (ArchiveDate) then
utilities.set_message ('err_archive_missing_date');
ArchiveDate = ''; -- empty string for concatenation
end
if "live" == UrlStatus then
arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
arch_text = cfg.messages['archived-unfit'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.set_message ('maint_unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. " " .. utilities.substitute ( arch_text,
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
arch_text = cfg.messages['archived-missing'];
if sepc ~= "." then arch_text = arch_text:lower() end
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local Lay = '';
local LaySource = A['LaySource'];
local LayURL = A['LayURL'];
local LayFormat = A['LayFormat'];
LayFormat = style_format (LayFormat, LayURL, 'lay-format', 'lay-url');
if utilities.is_set (LayURL) then
if utilities.is_set (LayDate) then LayDate = " (" .. LayDate .. ")" end
if utilities.is_set (LaySource) then
LaySource = " – ''" .. utilities.safe_for_italics (LaySource) .. "''";
else
LaySource = "";
end
if sepc == '.' then
Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate
else
Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate
end
elseif utilities.is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url=
Lay = sepc .. LayFormat; -- if set and LayURL not set, then LayFormat has error message
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher;
if utilities.is_set (PublicationDate) then
PublicationDate = wrap_msg ('published', PublicationDate);
end
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
else
Publisher = PublicationDate;
end
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
if utilities.is_set (Others) then Others = safe_join ({Others, sepc .. " "}, sepc) end -- add terminal punctuation & space; check for dup sepc; TODO why do we need to do this here?
tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc );
elseif utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join( {Title, TitleNote}, sepc ); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join( {Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
else
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
else -- a sheet or stand-alone map
tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc );
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join( {Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc );
else -- all other CS1 templates
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language,
Volume, Others, Edition, Publisher, Agency}, sepc );
end
if #ID_list > 0 then
ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
else
ID_list = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Lay, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Lay, Quote }, sepc );
end
local text;
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = " ";
local post_text = "";
if utilities.is_set (Chapter) and 0 == #c then
in_text = in_text .. cfg.messages['in'] .. " "
if (sepc ~= '.') then
in_text = in_text:lower() -- lowercase for cs2
end
end
if EditorCount <= 1 then
post_text = " (" .. cfg.messages['editor'] .. ")"; -- be consistent with no-author, no-date case
else
post_text = " (" .. cfg.messages['editors'] .. ")";
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. ", " .. cfg.messages['editor'];
else
Editors = Editors .. ", " .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
text = text:sub(1, -sepc:len() - 1);
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
local citeref_id;
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
options_t.id = Ref or citeref_id;
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass);
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local name = tostring (name);
local enum_name; -- for enumerated parameters, is name with enumerator replaced with '#'
local state;
local function state_test (state, name) -- local function to do testing of state values
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted
return nil;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list ) then -- limited parameter sets allowed for these templates
state = whitelist.limited_basic_arguments[name];
if true == state_test (state, name) then return true; end
state = whitelist.preprint_arguments[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test (state, name) then return true; end
-- limited enumerated parameters list
enum_name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
state = whitelist.limited_numbered_arguments[enum_name];
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list) then -- experiment for template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test (state, name) then return true; end
end -- if here, fall into general validation
state = whitelist.basic_arguments[name]; -- all other templates; all normal parameters allowed
if true == state_test (state, name) then return true; end
-- all enumerated parameters allowed
enum_name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
state = whitelist.numbered_arguments[enum_name];
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (url_param_t)
local url_error_t = {};
check_for_url (url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
This is used by templates such as {{cite book}} to create the actual citation text.
]]
local function citation(frame)
Frame = frame; -- save a copy in case we need to display an error message in preview mode
local sandbox = '/sandbox' -- i18n: replace this rvalue with the name that your wiki uses to identify sandbox subpages
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
local pframe = frame:getParent()
local styles;
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css';
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local args = {}; -- table where we store all of the template's arguments
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local config = {}; -- table to store parameters from the module {{#invoke:}}
for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame
config[k] = v;
-- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if ('string' == type (k)) then
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9
end
if not validate( k, config.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
if is_sandbox then -- did the {{#invoke:}} use sandbox version?
suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions/sandbox' ); -- use the sandbox version
else
suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions' ); -- use the live version
end
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
args[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
-- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep?
-- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that)
-- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here
end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact?
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local url_param_t = {};
for k, v in pairs( args ) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table
url_param_t[k] = v; -- make a parameter/value list for extraneous url check
end
end
has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong
return table.concat ({
frame:extensionTag ('templatestyles', '', {src=styles}),
citation0( config, args)
});
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {citation = citation};
5b914afd20bdaa8daab7192c9ee32f246e5bee9b
Albert Einstein
0
13
23
2022-07-02T03:18:28Z
SpaceMan
2
Albert Einstein
wikitext
text/x-wiki
Albert Einstein was born at Ulm, in Württemberg, Germany, on March 14, 1879. Six weeks later the family moved to Munich, where he later on began his schooling at the Luitpold Gymnasium. Later, they moved to Italy and Albert continued his education at Aarau, Switzerland and in 1896 he entered the Swiss Federal Polytechnic School in Zurich to be trained as a teacher in physics and mathematics. In 1901, the year he gained his diploma, he acquired Swiss citizenship and, as he was unable to find a teaching post, he accepted a position as technical assistant in the Swiss Patent Office. In 1905 he obtained his doctor’s degree.
During his stay at the Patent Office, and in his spare time, he produced much of his remarkable work and in 1908 he was appointed Privatdozent in Berne. In 1909 he became Professor Extraordinary at Zurich, in 1911 Professor of Theoretical Physics at Prague, returning to Zurich in the following year to fill a similar post. In 1914 he was appointed Director of the Kaiser Wilhelm Physical Institute and Professor in the University of Berlin. He became a German citizen in 1914 and remained in Berlin until 1933 when he renounced his citizenship for political reasons and emigrated to America to take the position of Professor of Theoretical Physics at Princeton*. He became a United States citizen in 1940 and retired from his post in 1945.
After World War II, Einstein was a leading figure in the World Government Movement, he was offered the Presidency of the State of Israel, which he declined, and he collaborated with Dr. Chaim Weizmann in establishing the Hebrew University of Jerusalem.
Einstein always appeared to have a clear view of the problems of physics and the determination to solve them. He had a strategy of his own and was able to visualize the main stages on the way to his goal. He regarded his major achievements as mere stepping-stones for the next advance.
At the start of his scientific work, Einstein realized the inadequacies of Newtonian mechanics and his special theory of relativity stemmed from an attempt to reconcile the laws of mechanics with the laws of the electromagnetic field. He dealt with classical problems of statistical mechanics and problems in which they were merged with quantum theory: this led to an explanation of the Brownian movement of molecules. He investigated the thermal properties of light with a low radiation density and his observations laid the foundation of the photon theory of light.
In his early days in Berlin, Einstein postulated that the correct interpretation of the special theory of relativity must also furnish a theory of gravitation and in 1916 he published his paper on the general theory of relativity. During this time he also contributed to the problems of the theory of radiation and statistical mechanics.
In the 1920s, Einstein embarked on the construction of unified field theories, although he continued to work on the probabilistic interpretation of quantum theory, and he persevered with this work in America. He contributed to statistical mechanics by his development of the quantum theory of a monatomic gas and he has also accomplished valuable work in connection with atomic transition probabilities and relativistic cosmology.
After his retirement he continued to work towards the unification of the basic concepts of physics, taking the opposite approach, geometrisation, to the majority of physicists.
Einstein’s researches are, of course, well chronicled and his more important works include Special Theory of Relativity (1905), Relativity (English translations, 1920 and 1950), General Theory of Relativity (1916), Investigations on Theory of Brownian Movement (1926), and The Evolution of Physics (1938). Among his non-scientific works, About Zionism (1930), Why War? (1933), My Philosophy (1934), and Out of My Later Years (1950) are perhaps the most important.
Albert Einstein received honorary doctorate degrees in science, medicine and philosophy from many European and American universities. During the 1920’s he lectured in Europe, America and the Far East, and he was awarded Fellowships or Memberships of all the leading scientific academies throughout the world. He gained numerous awards in recognition of his work, including the Copley Medal of the Royal Society of London in 1925, and the Franklin Medal of the Franklin Institute in 1935.
Einstein’s gifts inevitably resulted in his dwelling much in intellectual solitude and, for relaxation, music played an important part in his life. He married Mileva Maric in 1903 and they had a daughter and two sons; their marriage was dissolved in 1919 and in the same year he married his cousin, Elsa Löwenthal, who died in 1936. He died on April 18, 1955 at Princeton, New Jersey.
=== Works ===
[[Relativity]]
a8d4b1f819de9f8b0e75f7f7b5315dc62869cab8
25
23
2022-07-02T03:21:48Z
SpaceMan
2
wikitext
text/x-wiki
[[File:AlbertE.jpg|thumb|Albert Einstein]]
Albert Einstein was born at Ulm, in Württemberg, Germany, on March 14, 1879. Six weeks later the family moved to Munich, where he later on began his schooling at the Luitpold Gymnasium. Later, they moved to Italy and Albert continued his education at Aarau, Switzerland and in 1896 he entered the Swiss Federal Polytechnic School in Zurich to be trained as a teacher in physics and mathematics. In 1901, the year he gained his diploma, he acquired Swiss citizenship and, as he was unable to find a teaching post, he accepted a position as technical assistant in the Swiss Patent Office. In 1905 he obtained his doctor’s degree.
During his stay at the Patent Office, and in his spare time, he produced much of his remarkable work and in 1908 he was appointed Privatdozent in Berne. In 1909 he became Professor Extraordinary at Zurich, in 1911 Professor of Theoretical Physics at Prague, returning to Zurich in the following year to fill a similar post. In 1914 he was appointed Director of the Kaiser Wilhelm Physical Institute and Professor in the University of Berlin. He became a German citizen in 1914 and remained in Berlin until 1933 when he renounced his citizenship for political reasons and emigrated to America to take the position of Professor of Theoretical Physics at Princeton*. He became a United States citizen in 1940 and retired from his post in 1945.
After World War II, Einstein was a leading figure in the World Government Movement, he was offered the Presidency of the State of Israel, which he declined, and he collaborated with Dr. Chaim Weizmann in establishing the Hebrew University of Jerusalem.
Einstein always appeared to have a clear view of the problems of physics and the determination to solve them. He had a strategy of his own and was able to visualize the main stages on the way to his goal. He regarded his major achievements as mere stepping-stones for the next advance.
At the start of his scientific work, Einstein realized the inadequacies of Newtonian mechanics and his special theory of relativity stemmed from an attempt to reconcile the laws of mechanics with the laws of the electromagnetic field. He dealt with classical problems of statistical mechanics and problems in which they were merged with quantum theory: this led to an explanation of the Brownian movement of molecules. He investigated the thermal properties of light with a low radiation density and his observations laid the foundation of the photon theory of light.
In his early days in Berlin, Einstein postulated that the correct interpretation of the special theory of relativity must also furnish a theory of gravitation and in 1916 he published his paper on the general theory of relativity. During this time he also contributed to the problems of the theory of radiation and statistical mechanics.
In the 1920s, Einstein embarked on the construction of unified field theories, although he continued to work on the probabilistic interpretation of quantum theory, and he persevered with this work in America. He contributed to statistical mechanics by his development of the quantum theory of a monatomic gas and he has also accomplished valuable work in connection with atomic transition probabilities and relativistic cosmology.
After his retirement he continued to work towards the unification of the basic concepts of physics, taking the opposite approach, geometrisation, to the majority of physicists.
Einstein’s researches are, of course, well chronicled and his more important works include Special Theory of Relativity (1905), Relativity (English translations, 1920 and 1950), General Theory of Relativity (1916), Investigations on Theory of Brownian Movement (1926), and The Evolution of Physics (1938). Among his non-scientific works, About Zionism (1930), Why War? (1933), My Philosophy (1934), and Out of My Later Years (1950) are perhaps the most important.
Albert Einstein received honorary doctorate degrees in science, medicine and philosophy from many European and American universities. During the 1920’s he lectured in Europe, America and the Far East, and he was awarded Fellowships or Memberships of all the leading scientific academies throughout the world. He gained numerous awards in recognition of his work, including the Copley Medal of the Royal Society of London in 1925, and the Franklin Medal of the Franklin Institute in 1935.
Einstein’s gifts inevitably resulted in his dwelling much in intellectual solitude and, for relaxation, music played an important part in his life. He married Mileva Maric in 1903 and they had a daughter and two sons; their marriage was dissolved in 1919 and in the same year he married his cousin, Elsa Löwenthal, who died in 1936. He died on April 18, 1955 at Princeton, New Jersey.
=== Works ===
[[Relativity]]
afdccbf5e5b556ebc4660e527d3ee43dd582c518
26
25
2022-07-02T03:27:22Z
SpaceMan
2
wikitext
text/x-wiki
[[File:AlbertE.jpg|thumb|Albert Einstein]]
Albert Einstein was born at Ulm, in Württemberg, Germany, on March 14, 1879. Six weeks later the family moved to Munich, where he later on began his schooling at the Luitpold Gymnasium. Later, they moved to Italy and Albert continued his education at Aarau, Switzerland and in 1896 he entered the Swiss Federal Polytechnic School in Zurich to be trained as a teacher in physics and mathematics. In 1901, the year he gained his diploma, he acquired Swiss citizenship and, as he was unable to find a teaching post, he accepted a position as technical assistant in the Swiss Patent Office. In 1905 he obtained his doctor’s degree.
During his stay at the Patent Office, and in his spare time, he produced much of his remarkable work and in 1908 he was appointed Privatdozent in Berne. In 1909 he became Professor Extraordinary at Zurich, in 1911 Professor of Theoretical Physics at Prague, returning to Zurich in the following year to fill a similar post. In 1914 he was appointed Director of the Kaiser Wilhelm Physical Institute and Professor in the University of Berlin. He became a German citizen in 1914 and remained in Berlin until 1933 when he renounced his citizenship for political reasons and emigrated to America to take the position of Professor of Theoretical Physics at Princeton*. He became a United States citizen in 1940 and retired from his post in 1945.
After World War II, Einstein was a leading figure in the World Government Movement, he was offered the Presidency of the State of Israel, which he declined, and he collaborated with Dr. Chaim Weizmann in establishing the Hebrew University of Jerusalem.
Einstein always appeared to have a clear view of the problems of physics and the determination to solve them. He had a strategy of his own and was able to visualize the main stages on the way to his goal. He regarded his major achievements as mere stepping-stones for the next advance.
At the start of his scientific work, Einstein realized the inadequacies of Newtonian mechanics and his special theory of relativity stemmed from an attempt to reconcile the laws of mechanics with the laws of the electromagnetic field. He dealt with classical problems of statistical mechanics and problems in which they were merged with quantum theory: this led to an explanation of the Brownian movement of molecules. He investigated the thermal properties of light with a low radiation density and his observations laid the foundation of the photon theory of light.
In his early days in Berlin, Einstein postulated that the correct interpretation of the special theory of relativity must also furnish a theory of gravitation and in 1916 he published his paper on the general theory of relativity. During this time he also contributed to the problems of the theory of radiation and statistical mechanics.
In the 1920s, Einstein embarked on the construction of unified field theories, although he continued to work on the probabilistic interpretation of quantum theory, and he persevered with this work in America. He contributed to statistical mechanics by his development of the quantum theory of a monatomic gas and he has also accomplished valuable work in connection with atomic transition probabilities and relativistic cosmology.
After his retirement he continued to work towards the unification of the basic concepts of physics, taking the opposite approach, geometrisation, to the majority of physicists.
Einstein’s researches are, of course, well chronicled and his more important works include Special Theory of Relativity (1905), Relativity (English translations, 1920 and 1950), General Theory of Relativity (1916), Investigations on Theory of Brownian Movement (1926), and The Evolution of Physics (1938). Among his non-scientific works, About Zionism (1930), Why War? (1933), My Philosophy (1934), and Out of My Later Years (1950) are perhaps the most important.
Albert Einstein received honorary doctorate degrees in science, medicine and philosophy from many European and American universities. During the 1920’s he lectured in Europe, America and the Far East, and he was awarded Fellowships or Memberships of all the leading scientific academies throughout the world. He gained numerous awards in recognition of his work, including the Copley Medal of the Royal Society of London in 1925, and the Franklin Medal of the Franklin Institute in 1935.
Einstein’s gifts inevitably resulted in his dwelling much in intellectual solitude and, for relaxation, music played an important part in his life. He married Mileva Maric in 1903 and they had a daughter and two sons; their marriage was dissolved in 1919 and in the same year he married his cousin, Elsa Löwenthal, who died in 1936. He died on April 18, 1955 at Princeton, New Jersey.
=== Works ===
[[Relativity]]
51f57e555efb1217535a6b269fb687a83b8c351e
27
26
2022-07-02T03:33:39Z
SpaceMan
2
wikitext
text/x-wiki
[[File:AlbertE.jpg|thumb|Albert Einstein]]
{| class="wikitable"
|-
! Born
! 14 March 1879<br />Ulm, Kingdom of Württemberg, German Empire
|-
| Died
| 18 April 1955 (aged 76)<br />Princeton, New Jersey, U.S.
|- style="text-align:center;"
| Known for
| style="text-align:left;" | General relativity<br />Special relativity<br />Photoelectric effect<br />E=mc2 (Mass–energy equivalence)<br />E=hf (Planck–Einstein relation)<br />Theory of Brownian motion<br />Einstein field equations<br />Bose–Einstein statistics<br />Bose–Einstein condensate<br />Gravitational wave<br />Cosmological constant<br />Unified field theory<br />EPR paradox<br />Ensemble interpretation<br />List of other concepts
|}
Albert Einstein was born at Ulm, in Württemberg, Germany, on March 14, 1879. Six weeks later the family moved to Munich, where he later on began his schooling at the Luitpold Gymnasium. Later, they moved to Italy and Albert continued his education at Aarau, Switzerland and in 1896 he entered the Swiss Federal Polytechnic School in Zurich to be trained as a teacher in physics and mathematics. In 1901, the year he gained his diploma, he acquired Swiss citizenship and, as he was unable to find a teaching post, he accepted a position as technical assistant in the Swiss Patent Office. In 1905 he obtained his doctor’s degree.
During his stay at the Patent Office, and in his spare time, he produced much of his remarkable work and in 1908 he was appointed Privatdozent in Berne. In 1909 he became Professor Extraordinary at Zurich, in 1911 Professor of Theoretical Physics at Prague, returning to Zurich in the following year to fill a similar post. In 1914 he was appointed Director of the Kaiser Wilhelm Physical Institute and Professor in the University of Berlin. He became a German citizen in 1914 and remained in Berlin until 1933 when he renounced his citizenship for political reasons and emigrated to America to take the position of Professor of Theoretical Physics at Princeton*. He became a United States citizen in 1940 and retired from his post in 1945.
After World War II, Einstein was a leading figure in the World Government Movement, he was offered the Presidency of the State of Israel, which he declined, and he collaborated with Dr. Chaim Weizmann in establishing the Hebrew University of Jerusalem.
Einstein always appeared to have a clear view of the problems of physics and the determination to solve them. He had a strategy of his own and was able to visualize the main stages on the way to his goal. He regarded his major achievements as mere stepping-stones for the next advance.
At the start of his scientific work, Einstein realized the inadequacies of Newtonian mechanics and his special theory of relativity stemmed from an attempt to reconcile the laws of mechanics with the laws of the electromagnetic field. He dealt with classical problems of statistical mechanics and problems in which they were merged with quantum theory: this led to an explanation of the Brownian movement of molecules. He investigated the thermal properties of light with a low radiation density and his observations laid the foundation of the photon theory of light.
In his early days in Berlin, Einstein postulated that the correct interpretation of the special theory of relativity must also furnish a theory of gravitation and in 1916 he published his paper on the general theory of relativity. During this time he also contributed to the problems of the theory of radiation and statistical mechanics.
In the 1920s, Einstein embarked on the construction of unified field theories, although he continued to work on the probabilistic interpretation of quantum theory, and he persevered with this work in America. He contributed to statistical mechanics by his development of the quantum theory of a monatomic gas and he has also accomplished valuable work in connection with atomic transition probabilities and relativistic cosmology.
After his retirement he continued to work towards the unification of the basic concepts of physics, taking the opposite approach, geometrisation, to the majority of physicists.
Einstein’s researches are, of course, well chronicled and his more important works include Special Theory of Relativity (1905), Relativity (English translations, 1920 and 1950), General Theory of Relativity (1916), Investigations on Theory of Brownian Movement (1926), and The Evolution of Physics (1938). Among his non-scientific works, About Zionism (1930), Why War? (1933), My Philosophy (1934), and Out of My Later Years (1950) are perhaps the most important.
Albert Einstein received honorary doctorate degrees in science, medicine and philosophy from many European and American universities. During the 1920’s he lectured in Europe, America and the Far East, and he was awarded Fellowships or Memberships of all the leading scientific academies throughout the world. He gained numerous awards in recognition of his work, including the Copley Medal of the Royal Society of London in 1925, and the Franklin Medal of the Franklin Institute in 1935.
Einstein’s gifts inevitably resulted in his dwelling much in intellectual solitude and, for relaxation, music played an important part in his life. He married Mileva Maric in 1903 and they had a daughter and two sons; their marriage was dissolved in 1919 and in the same year he married his cousin, Elsa Löwenthal, who died in 1936. He died on April 18, 1955 at Princeton, New Jersey.
=== Works ===
[[Relativity]]
7ffc6859fae04e428dce9ffc3b6b531f1b58baed
28
27
2022-07-02T03:34:35Z
SpaceMan
2
Protected "[[Albert Einstein]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
[[File:AlbertE.jpg|thumb|Albert Einstein]]
{| class="wikitable"
|-
! Born
! 14 March 1879<br />Ulm, Kingdom of Württemberg, German Empire
|-
| Died
| 18 April 1955 (aged 76)<br />Princeton, New Jersey, U.S.
|- style="text-align:center;"
| Known for
| style="text-align:left;" | General relativity<br />Special relativity<br />Photoelectric effect<br />E=mc2 (Mass–energy equivalence)<br />E=hf (Planck–Einstein relation)<br />Theory of Brownian motion<br />Einstein field equations<br />Bose–Einstein statistics<br />Bose–Einstein condensate<br />Gravitational wave<br />Cosmological constant<br />Unified field theory<br />EPR paradox<br />Ensemble interpretation<br />List of other concepts
|}
Albert Einstein was born at Ulm, in Württemberg, Germany, on March 14, 1879. Six weeks later the family moved to Munich, where he later on began his schooling at the Luitpold Gymnasium. Later, they moved to Italy and Albert continued his education at Aarau, Switzerland and in 1896 he entered the Swiss Federal Polytechnic School in Zurich to be trained as a teacher in physics and mathematics. In 1901, the year he gained his diploma, he acquired Swiss citizenship and, as he was unable to find a teaching post, he accepted a position as technical assistant in the Swiss Patent Office. In 1905 he obtained his doctor’s degree.
During his stay at the Patent Office, and in his spare time, he produced much of his remarkable work and in 1908 he was appointed Privatdozent in Berne. In 1909 he became Professor Extraordinary at Zurich, in 1911 Professor of Theoretical Physics at Prague, returning to Zurich in the following year to fill a similar post. In 1914 he was appointed Director of the Kaiser Wilhelm Physical Institute and Professor in the University of Berlin. He became a German citizen in 1914 and remained in Berlin until 1933 when he renounced his citizenship for political reasons and emigrated to America to take the position of Professor of Theoretical Physics at Princeton*. He became a United States citizen in 1940 and retired from his post in 1945.
After World War II, Einstein was a leading figure in the World Government Movement, he was offered the Presidency of the State of Israel, which he declined, and he collaborated with Dr. Chaim Weizmann in establishing the Hebrew University of Jerusalem.
Einstein always appeared to have a clear view of the problems of physics and the determination to solve them. He had a strategy of his own and was able to visualize the main stages on the way to his goal. He regarded his major achievements as mere stepping-stones for the next advance.
At the start of his scientific work, Einstein realized the inadequacies of Newtonian mechanics and his special theory of relativity stemmed from an attempt to reconcile the laws of mechanics with the laws of the electromagnetic field. He dealt with classical problems of statistical mechanics and problems in which they were merged with quantum theory: this led to an explanation of the Brownian movement of molecules. He investigated the thermal properties of light with a low radiation density and his observations laid the foundation of the photon theory of light.
In his early days in Berlin, Einstein postulated that the correct interpretation of the special theory of relativity must also furnish a theory of gravitation and in 1916 he published his paper on the general theory of relativity. During this time he also contributed to the problems of the theory of radiation and statistical mechanics.
In the 1920s, Einstein embarked on the construction of unified field theories, although he continued to work on the probabilistic interpretation of quantum theory, and he persevered with this work in America. He contributed to statistical mechanics by his development of the quantum theory of a monatomic gas and he has also accomplished valuable work in connection with atomic transition probabilities and relativistic cosmology.
After his retirement he continued to work towards the unification of the basic concepts of physics, taking the opposite approach, geometrisation, to the majority of physicists.
Einstein’s researches are, of course, well chronicled and his more important works include Special Theory of Relativity (1905), Relativity (English translations, 1920 and 1950), General Theory of Relativity (1916), Investigations on Theory of Brownian Movement (1926), and The Evolution of Physics (1938). Among his non-scientific works, About Zionism (1930), Why War? (1933), My Philosophy (1934), and Out of My Later Years (1950) are perhaps the most important.
Albert Einstein received honorary doctorate degrees in science, medicine and philosophy from many European and American universities. During the 1920’s he lectured in Europe, America and the Far East, and he was awarded Fellowships or Memberships of all the leading scientific academies throughout the world. He gained numerous awards in recognition of his work, including the Copley Medal of the Royal Society of London in 1925, and the Franklin Medal of the Franklin Institute in 1935.
Einstein’s gifts inevitably resulted in his dwelling much in intellectual solitude and, for relaxation, music played an important part in his life. He married Mileva Maric in 1903 and they had a daughter and two sons; their marriage was dissolved in 1919 and in the same year he married his cousin, Elsa Löwenthal, who died in 1936. He died on April 18, 1955 at Princeton, New Jersey.
=== Works ===
[[Relativity]]
7ffc6859fae04e428dce9ffc3b6b531f1b58baed
File:AlbertE.jpg
6
14
24
2022-07-02T03:20:47Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=Albert Einstein}}
|date=2022-07-02
|source={{own}}
|author=[[User:SpaceMan|Astrobase ]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
[[Category:Scientist]]
f6767cfb3458fd6198b477e4c6897767651fc5c0
Relativity
0
15
29
2022-07-02T03:36:21Z
SpaceMan
2
Created page with "General relativity is concerned with [[gravity]], one of the fundamental forces in the universe. Gravity defines macroscopic behaviour, and so general relativity describes large-scale physical phenomena. It was conceived by [[Albert Einstein]] in 1916 General relativity follows from Einstein’s principle of equivalence: on a local scale it is impossible to distinguish between physical effects due to gravity and those due to acceleration. Gravity is treated as a geome..."
wikitext
text/x-wiki
General relativity is concerned with [[gravity]], one of the fundamental forces in the universe. Gravity defines macroscopic behaviour, and so general relativity describes large-scale physical phenomena.
It was conceived by [[Albert Einstein]] in 1916
General relativity follows from Einstein’s principle of equivalence: on a local scale it is impossible to distinguish between physical effects due to gravity and those due to acceleration. Gravity is treated as a geometric phenomenon that arises from the curvature of space-time. The solution of the field equations that describe general relativity can yield answers to different physical situations, such as planetary dynamics, the birth and death of [[stars]], [[black holes]], and the evolution of the universe. General relativity has been experimentally verified by observations of gravitational lenses, the orbit of the planet [[Mercury]], the dilation of time in Earth’s gravitational field, and gravitational waves from merging black holes.
9f183f4d6800a1df9b286767c4660838da6d15a5
SpaceMan:General disclaimer
4
16
31
2022-07-02T04:38:48Z
SpaceMan
2
Disclaimer
wikitext
text/x-wiki
===DISCLAIMER===
Last updated July 02, 2022
===WEBSITE DISCLAIMER===
The information provided by Astrobase ('we', 'us', or 'our') on https://astrobase.miraheze.org/ (the 'Site') is for general informational purposes only. All information on the Site is provided in good faith.
===EXTERNAL LINKS DISCLAIMER===
The Site may contain (or you may be sent through the Site) links to other websites or content belonging to or originating from third parties or links to websites and features in banners or other advertising. Such external links are not investigated, monitored, or checked for accuracy, adequacy, validity, reliability, availability, or completeness by us. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR RELIABILITY OF ANY INFORMATION OFFERED BY THIRD-PARTY WEBSITES LINKED THROUGH THE SITE OR ANY WEBSITE OR FEATURE LINKED IN ANY BANNER OR OTHER ADVERTISING. WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES.
===PROFESSIONAL DISCLAIMER===
The Site cannot and does not contain science advice. The science information is provided for general informational and educational purposes only and is not a substitute for professional advice. Accordingly, before taking any actions based upon such information, we encourage you to consult with the appropriate professionals. We do not provide any kind of science advice. THE USE OR RELIANCE OF ANY INFORMATION CONTAINED ON THE SITE IS SOLELY AT YOUR OWN RISK.
9137a48227cc9ce58e1382afd7c0c6acc9d47970
32
31
2022-07-02T04:39:57Z
SpaceMan
2
Protected "[[AstroBase:General disclaimer]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
===DISCLAIMER===
Last updated July 02, 2022
===WEBSITE DISCLAIMER===
The information provided by Astrobase ('we', 'us', or 'our') on https://astrobase.miraheze.org/ (the 'Site') is for general informational purposes only. All information on the Site is provided in good faith.
===EXTERNAL LINKS DISCLAIMER===
The Site may contain (or you may be sent through the Site) links to other websites or content belonging to or originating from third parties or links to websites and features in banners or other advertising. Such external links are not investigated, monitored, or checked for accuracy, adequacy, validity, reliability, availability, or completeness by us. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR RELIABILITY OF ANY INFORMATION OFFERED BY THIRD-PARTY WEBSITES LINKED THROUGH THE SITE OR ANY WEBSITE OR FEATURE LINKED IN ANY BANNER OR OTHER ADVERTISING. WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES.
===PROFESSIONAL DISCLAIMER===
The Site cannot and does not contain science advice. The science information is provided for general informational and educational purposes only and is not a substitute for professional advice. Accordingly, before taking any actions based upon such information, we encourage you to consult with the appropriate professionals. We do not provide any kind of science advice. THE USE OR RELIANCE OF ANY INFORMATION CONTAINED ON THE SITE IS SOLELY AT YOUR OWN RISK.
9137a48227cc9ce58e1382afd7c0c6acc9d47970
SpaceMan:Copyrights
4
17
33
2022-07-02T04:43:41Z
SpaceMan
2
Copyright
wikitext
text/x-wiki
===Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)===
This is a human-readable summary of (and not a substitute for) the license. Disclaimer.
You are free to:
Share — copy and redistribute the material in any medium or format
Adapt — remix, transform, and build upon the material
for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
===Under the following terms:===
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
fa8920aeca08f6d853143e56c2adbea7d9b92f28
34
33
2022-07-02T04:43:57Z
SpaceMan
2
Protected "[[AstroBase:Copyrights]]" ([Edit=Allow only administrators] (indefinite))
wikitext
text/x-wiki
===Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)===
This is a human-readable summary of (and not a substitute for) the license. Disclaimer.
You are free to:
Share — copy and redistribute the material in any medium or format
Adapt — remix, transform, and build upon the material
for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
===Under the following terms:===
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
fa8920aeca08f6d853143e56c2adbea7d9b92f28
Astronomy
0
10
35
19
2022-07-02T08:05:23Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
== Definition ==
*
Astronomy (from Ancient Greek ἀστρονομία (astronomía) 'science that studies the laws of the stars') is a natural science that studies celestial objects and phenomena. It uses [[mathematics]], [[physics]], and <nowiki> [[chemistry]] </nowiki>in order to explain their origin and evolution. Objects of interest include [[planets]], [[moons]], [[stars]], [[nebulae]], [[galaxies]], and [[comets]]. Relevant phenomena include [[supernova explosions]], [[gamma ray bursts]], [[quasars]], [[blazars]], [[pulsars]], and [[cosmic microwave background radiation]]. More generally, astronomy studies everything that originates beyond Earth's atmosphere. Cosmology is a branch of astronomy that studies the universe as a whole.
Astronomy is one of the oldest natural sciences. The early civilizations in recorded history made methodical observations of the night sky. These include the Babylonians, Greeks, Indians, Egyptians, Chinese, Maya, and many ancient indigenous peoples of the Americas. In the past, astronomy included disciplines as diverse as astrometry, celestial navigation, observational astronomy, and the making of calendars. Nowadays, professional astronomy is often said to be the same as astrophysics.
Professional astronomy is split into observational and theoretical branches. Observational astronomy is focused on acquiring data from observations of astronomical objects. This data is then analyzed using basic principles of physics. Theoretical astronomy is oriented toward the development of computer or analytical models to describe astronomical objects and phenomena. These two fields complement each other. Theoretical astronomy seeks to explain observational results and observations are used to confirm theoretical results.
Astronomy is one of the few sciences in which amateurs play an active role. This is especially true for the discovery and observation of transient events. Amateur astronomers have helped with many important discoveries, such as finding new comets.
[[File:Astronomy.jpg|thumb|Astronomy picture]]
096c6b94e0f24eb914c9252595e6e0e08eb6cfbc
Gravity
0
18
36
2022-07-02T08:08:39Z
SpaceMan
2
Created page with "===Definition=== Gravitation is defined as the force of attraction between any two bodies in the universe. The earth attracts (or pulls) all objects lying on or near its surface towards its centre. The [[Force]] with which the earth pulls the objects towards its centre is called the gravitational force of the earth or gravity of the earth. ==Universal Law of Gravitation== Universal law of gravitation was given by *[[Isaac Newton]]. According to this law, the atractive..."
wikitext
text/x-wiki
===Definition===
Gravitation is defined as the force of attraction between any two bodies in the universe. The earth attracts (or pulls) all objects lying on or near its surface towards its centre. The [[Force]] with which the earth pulls the objects towards its centre is called the gravitational force of the earth or gravity of the earth.
==Universal Law of Gravitation==
Universal law of gravitation was given by *[[Isaac Newton]]. According to this law, the atractive force between any two objects in the universe is directly proportional to the product of their masses([[Mass]]) and inversely proportional to the square of [[distance]] between them. e direction of the force is along the line joining the centres of two objects.
==Newton's law of universal gravitation==
1. Force is directly proportional to product of masses of bodies.
2. It is indirectly proportional to distance between bodies.
3. Formula for F = G*m1*m2/d²
Where G is the constant of gravity and m1 and M2 are the masses of bodies and d² is the square of [[distance]] between them.
7249b23c7a172df6f5edfbf5f01f02a9fd1fd18e
37
36
2022-07-02T08:09:13Z
SpaceMan
2
Protected "[[Gravity]]" ([Edit=Allow only autoconfirmed users] (indefinite) [Move=Allow only autoconfirmed users] (indefinite))
wikitext
text/x-wiki
===Definition===
Gravitation is defined as the force of attraction between any two bodies in the universe. The earth attracts (or pulls) all objects lying on or near its surface towards its centre. The [[Force]] with which the earth pulls the objects towards its centre is called the gravitational force of the earth or gravity of the earth.
==Universal Law of Gravitation==
Universal law of gravitation was given by *[[Isaac Newton]]. According to this law, the atractive force between any two objects in the universe is directly proportional to the product of their masses([[Mass]]) and inversely proportional to the square of [[distance]] between them. e direction of the force is along the line joining the centres of two objects.
==Newton's law of universal gravitation==
1. Force is directly proportional to product of masses of bodies.
2. It is indirectly proportional to distance between bodies.
3. Formula for F = G*m1*m2/d²
Where G is the constant of gravity and m1 and M2 are the masses of bodies and d² is the square of [[distance]] between them.
7249b23c7a172df6f5edfbf5f01f02a9fd1fd18e
Isaac Newton
0
19
38
2022-07-02T08:10:58Z
SpaceMan
2
Created page with "Isaac was born in Woolsthorpe near Grantham, England. He is generally regarded as the most original and influential theorist in the history of [[science]]. He was born in a poor farming family. But he was not good at farming. He was sent to study at [[Cambridge University]] in 1661. In 1665 a plague broke out in Cambridge and so Newton took a year off. It was during this year that the incident of the apple falling on him is said to have occurred. This incident prompted N..."
wikitext
text/x-wiki
Isaac was born in Woolsthorpe near Grantham, England. He is generally regarded as the most original and influential theorist in the history of [[science]]. He was born in a poor farming family. But he was not good at farming. He was sent to study at [[Cambridge University]] in 1661. In 1665 a plague broke out in Cambridge and so Newton took a year off. It was during this year that the incident of the apple falling on him is said to have occurred. This incident prompted Newton to explore the possibility of connecting [[gravity]] with the force that kept the tacon in its orbit. This led him to the universal law of gravitation. It is remarkable that many great scientists before him knew of gravity but failed to realise it.
Newton formulated the well-known laws of
motion. He worked on theories of light and colour. He designed an astronomical telescope to carry out astronomical observations. Newton was also a great mathematician. He invented a new branch of mathematics, called [[calculus]]. He used it to prove that for objects outside a sphere of uniform [[density]], the sphere behaves as if the whole of its mass is concentrated at its centre. Newton transformed the structure of physical science with his three laws of motion and the universal law of gravitation. As the keystone of the scientific revolution of the seventeenth century, Newton's work combined the contributions of [[Copernicus]], [[Kepler]], [[Galileo]], and others into a new powerful synthesis.
It is remarkable that though the gravitational theory could not be verified at that time, there was hardly any doubt about its correctness. This is because Newton based his theory on sound scientific reasoning and backed it with mathematics. This made the theory simple and elegant. These qualities are now recognised as essential requirements of a good scientific theory.
1fd01f0c5d36d16a58da557daa55ec1b9c343fa0
Main Page
0
1
39
30
2022-07-02T08:16:29Z
SpaceMan
2
/* Quick List */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
===Quick List===
[[Special:ListUsers]]
[[https://astrobase.miraheze.org/wiki/Special:WantedPages|Wanted Pages]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
0395653c2c3d84e4e22b228af6000f34a48e7812
40
39
2022-07-02T08:17:19Z
SpaceMan
2
/* Quick List */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
===Quick List===
[[Special:ListUsers]]
[[Special:WantedPages]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
97c916f547bcf72172ae6147276d60bb13f4fd29
56
40
2022-07-17T09:25:07Z
SpaceMan
2
/* Quick List */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
===Quick List===
[[Special:All Pages ]]
[[Special:ListUsers]]
[[Special:WantedPages]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
b38d0bbff7ddb457d30de7c5340c15327f358ef2
57
56
2022-07-17T09:25:36Z
SpaceMan
2
/* Quick List */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
Welcome to AstroBase , a knowledge base created especially for Astronomy. Please help us create a Knowledge base for Astronomy. This wiki is hosted in Miraheze and a lot of credit goes to them.
===Quick List===
[[Special:AllPages ]]
[[Special:ListUsers]]
[[Special:WantedPages]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
2811d833f7ba2698e712a57ea6d0f8d467892558
60
57
2022-08-27T13:10:53Z
SpaceMan
2
/* Welcome to {{SITENAME}}! */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently a developing project.
===Quick List===
[[Special:AllPages ]]
[[Special:ListUsers]]
[[Special:WantedPages]]
=== Miraheze ===
* [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users)
* [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]]
* [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.)
* [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]]
* On [[phab:|Phabricator]]
* On [https://miraheze.org/discord Discord]
* On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat])
__INDEX__
__NEWSECTIONLINK__
5e426a1fa7e148ec0166e9977e84d4acecc3570a
61
60
2022-08-27T14:20:22Z
SpaceMan
2
/* Miraheze */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently a developing project.
===Quick List===
[[Special:AllPages ]]
[[Special:ListUsers]]
[[Special:WantedPages]]
f04a27b1543292aacbf1264357e019a30d6b5603
62
61
2022-08-27T14:21:29Z
SpaceMan
2
/* Quick List */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently a developing project.
===Quick List===
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
5c60d9048c6e47b8adb8037d2ddfa0e990fb345a
66
62
2022-08-27T14:35:41Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently a developing project.
===Quick List===
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
===Astronomy Database Portal===
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
4778c92828aa70e7237ea35f26c04851464f8b86
Star
0
20
41
2022-07-02T08:21:05Z
SpaceMan
2
Star
wikitext
text/x-wiki
===Definition===
A star is an astronomical object comprising a luminous spheroid of [[plasma]] held together by its gravity. The nearest star to [[Earth]] is the [[Sun]]. Many other stars are visible to the naked eye at night, but their immense distances from Earth make them appear as fixed points of [[light]]. The most prominent stars have been categorised into [[constellations]] and [[asterisms]], and many of the brightest stars have proper names. [[Astronomes]] have assembled star catalogues that identify the known stars and provide standardized stellar designations. The observable universe contains an estimated 10²² to 10²⁴ stars. Still, most are invisible to the naked eye from Earth, including all individual stars outside our [[galaxy]], the [[Milky Way]]. A star's life begins with the gravitational([[Gravity]]) collapse of a gaseous [[nebula]] of material composed primarily of [[hydrogen]], along with [[helium]] and trace amounts of heavier elements. Its total mass is the main factor determining its evolution and eventual fate.
51d29fac79f9b36c655eb27f747ca42aa2fc1eb2
43
41
2022-07-02T08:26:54Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
===Definition===
[[[[File:Sunastronomy.jpg|thumb|Sun]]|thumb|alt=Sun|Sun]]
A star is an astronomical object comprising a luminous spheroid of [[plasma]] held together by its gravity. The nearest star to [[Earth]] is the [[Sun]]. Many other stars are visible to the naked eye at night, but their immense distances from Earth make them appear as fixed points of [[light]]. The most prominent stars have been categorised into [[constellations]] and [[asterisms]], and many of the brightest stars have proper names. [[Astronomes]] have assembled star catalogues that identify the known stars and provide standardized stellar designations. The observable universe contains an estimated 10²² to 10²⁴ stars. Still, most are invisible to the naked eye from Earth, including all individual stars outside our [[galaxy]], the [[Milky Way]]. A star's life begins with the gravitational([[Gravity]]) collapse of a gaseous [[nebula]] of material composed primarily of [[hydrogen]], along with [[helium]] and trace amounts of heavier elements. Its total mass is the main factor determining its evolution and eventual fate.
95fb79210545de7a6810e7ac32124cba95a7ef41
44
43
2022-07-02T08:31:58Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
===Definition===
[[File:Sunastronomy.jpg|thumb|Sun]]
A star is an astronomical object comprising a luminous spheroid of [[plasma]] held together by its gravity. The nearest star to [[Earth]] is the [[Sun]]. Many other stars are visible to the naked eye at night, but their immense distances from Earth make them appear as fixed points of [[light]]. The most prominent stars have been categorised into [[constellations]] and [[asterisms]], and many of the brightest stars have proper names. [[Astronomes]] have assembled star catalogues that identify the known stars and provide standardized stellar designations. The observable universe contains an estimated 10²² to 10²⁴ stars. Still, most are invisible to the naked eye from Earth, including all individual stars outside our [[galaxy]], the [[Milky Way]]. A star's life begins with the gravitational([[Gravity]]) collapse of a gaseous [[nebula]] of material composed primarily of [[hydrogen]], along with [[helium]] and trace amounts of heavier elements. Its total mass is the main factor determining its evolution and eventual fate.
d7f24cbb0d64aaf2328c53cea37398b33c97b559
45
44
2022-07-02T08:33:43Z
SpaceMan
2
SpaceMan moved page [[Stars]] to [[Star]]: Wrong name
wikitext
text/x-wiki
===Definition===
[[File:Sunastronomy.jpg|thumb|Sun]]
A star is an astronomical object comprising a luminous spheroid of [[plasma]] held together by its gravity. The nearest star to [[Earth]] is the [[Sun]]. Many other stars are visible to the naked eye at night, but their immense distances from Earth make them appear as fixed points of [[light]]. The most prominent stars have been categorised into [[constellations]] and [[asterisms]], and many of the brightest stars have proper names. [[Astronomes]] have assembled star catalogues that identify the known stars and provide standardized stellar designations. The observable universe contains an estimated 10²² to 10²⁴ stars. Still, most are invisible to the naked eye from Earth, including all individual stars outside our [[galaxy]], the [[Milky Way]]. A star's life begins with the gravitational([[Gravity]]) collapse of a gaseous [[nebula]] of material composed primarily of [[hydrogen]], along with [[helium]] and trace amounts of heavier elements. Its total mass is the main factor determining its evolution and eventual fate.
d7f24cbb0d64aaf2328c53cea37398b33c97b559
File:Sunastronomy.jpg
6
21
42
2022-07-02T08:24:54Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=Sun in astronomy}}
|date=2022-07-02
|source={{own}}
|author=[[User:SpaceMan|Astrobase ]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
[[Category:Star]]
[[Category:Astronomy]]
bbc1da1cea1f98aef83543f8b0f83e07975b8275
Stars
0
22
46
2022-07-02T08:33:44Z
SpaceMan
2
SpaceMan moved page [[Stars]] to [[Star]]: Wrong name
wikitext
text/x-wiki
#REDIRECT [[Star]]
0d95576f1993901f134db7a5aa54b73e8ffa2754
Grand Unified Theory
0
23
47
2022-07-08T07:43:11Z
SpaceMan
2
Created page with " The grand unified theory (GUT) is a theory that remains elusive and complex, but scientists are still working on it. If it is correct, it would explain many observations made in physics and chemistry - from the structure of atoms to the behavior of subatomic particles. While this theory remains undiscovered, there's no doubt that ongoing research will lead to even more revelations about the nature of reality. ===Classic theory=== GUT theory is one of the most popular t..."
wikitext
text/x-wiki
The grand unified theory (GUT) is a theory that remains elusive and complex, but scientists are still working on it. If it is correct, it would explain many observations made in physics and chemistry - from the structure of atoms to the behavior of subatomic particles. While this theory remains undiscovered, there's no doubt that ongoing research will lead to even more revelations about the nature of reality.
===Classic theory===
GUT theory is one of the most popular theories in physics today. It was first proposed by German physicist, [[Max Planck]] in 1900 and has been revised and expanded many times since then. GUT theory is a theory that explains how the [[universe]] works.
===Modern progress===
There is no doubt that the GUT (Gravitation, Unification and Theories) theory is of immense importance. Originally conceived over a hundred years ago, scientists are still uncovering new information about it every day. Despite its age, the GUT theory remains one of the most comprehensive theories in existence today - unifying various fields of physics under one umbrella. Its implications for modern scientific theories cannot be overemphasized.
===Introduction to the Great Theory===
The grand unified theory (GUT), or the great theory, is a theory of quantum mechanics that attempts to explain all the known forces in the universe. It's been controversial since its inception, but it continues to be studied and debated by scientists today. Regardless of whether or not you agree with the GUT, it's an interesting theory worth exploring! Some believe that the GUT is responsible for explaining how particles interact, while others think it has broader implications. For example, some believe that the GUT is responsible for the development of the universe as we know it.
The grand unified theory (GUT) is a proposed scientific theory that has been theorized for over 50 years but remains unconfirmed due to its complexity. If it is proven correct, it would greatly affect our understanding of the universe and our place within it. Although there is much speculation surrounding GUT, if it proves true it could have far-reaching consequences for physics and astronomy research.
4b77d75c4052a2e1c4441419d54ffe3213af1877
Astrophysics
0
24
49
48
2022-07-08T17:19:18Z
SpaceMan
2
1 revision imported: Astrophysics
wikitext
text/x-wiki
{{short description|Branch of astronomy}}
{{About|the use of physics to determine the nature of astronomical objects|the use of physics to determine their positions and motions|Celestial mechanics|the physical study of the largest-scale structures of the universe|Physical cosmology|the journal|Astrophysics (journal)}}
{{TopicTOC-Physics}}
'''Astrophysics''' is a science that employs the methods and principles of [[physics]] and [[chemistry]] in the study of [[astronomical object]]s and phenomena.<ref>{{cite book |title=Astrophysics in a Nutshell |first=Dan |last=Maoz |date=23 February 2016 |publisher=Princeton University Press |pages=272 |isbn=9781400881178 |url=https://www.google.com/books/edition/Astrophysics_in_a_Nutshell/bmBeCwAAQBAJ?hl=en&gbpv=1&dq=%22astrophysics+is%22&pg=PA1&printsec=frontcover}}</ref><ref>{{cite web | title=astrophysics | publisher=Merriam-Webster, Incorporated | url=http://www.merriam-webster.com/dictionary/astrophysics | access-date=2011-05-22 | archive-url= https://web.archive.org/web/20110610085146/http://www.merriam-webster.com/dictionary/astrophysics| archive-date= 10 June 2011 | url-status= live}}</ref> As one of the founders of the discipline said, Astrophysics "seeks to ascertain the nature of the heavenly bodies, rather than their positions or motions in space–''what'' they are, rather than ''where'' they are."<ref>{{Citation | last = Keeler | first = James E. | author-link = James E. Keeler | title = The Importance of Astrophysical Research and the Relation of Astrophysics to the Other Physical Sciences | journal = The Astrophysical Journal | volume = 6 | issue = 4 | pages = 271–288 | date = November 1897 | bibcode = 1897ApJ.....6..271K |doi = 10.1086/140401 | pmid = 17796068 }}</ref> Among the subjects studied are the [[Sun]], other [[star]]s, [[galaxy|galaxies]], [[extrasolar planet]]s, the [[interstellar medium]] and the [[cosmic microwave background]].<ref name="nasa.gov">{{cite web|url=https://science.nasa.gov/astrophysics/focus-areas/|title=Focus Areas – NASA Science|work=nasa.gov}}</ref><ref>{{cite encyclopedia|url=https://www.britannica.com/EBchecked/topic/40047/astronomy|title=astronomy|encyclopedia=Encyclopædia Britannica}}</ref> Emissions from these objects are examined across all parts of the [[electromagnetic spectrum]], and the properties examined include [[luminosity]], [[density]], [[temperature]], and [[chemistry|chemical]] composition. Because astrophysics is a very broad subject, ''astrophysicists'' apply concepts and methods from many disciplines of physics and chemistry, including [[classical mechanics]], [[electromagnetism]], [[statistical mechanics]], [[thermodynamics]], [[quantum mechanics]], [[theory of relativity|relativity]], [[nuclear physics|nuclear]] and [[particle physics]], and [[atomic, molecular, and optical physics|atomic and molecular physics]].
In practice, modern astronomical research often involves a substantial amount of work in the realms of [[Theoretical physics|theoretical]] and observational physics. Some areas of study for astrophysicists include their attempts to determine the properties of [[dark matter]], [[dark energy]], [[black holes]], and other [[celestial bodies]]; and the [[Cosmogony|origin]] and [[ultimate fate of the universe]].<ref name="nasa.gov"/> Topics also studied by theoretical astrophysicists include [[Formation and evolution of the Solar System|Solar System formation and evolution]]; [[stellar dynamics]] and [[Stellar evolution|evolution]]; [[galaxy formation and evolution]]; [[magnetohydrodynamics]]; [[large-scale structure of the universe|large-scale structure]] of [[matter]] in the universe; origin of [[cosmic ray]]s; [[general relativity]], [[special relativity]], [[quantum cosmology|quantum]] and [[physical cosmology]], including [[string theory|string]] cosmology and [[astroparticle physics]].
==History==
[[Image:NIEdot362.jpg|thumb|left|200px|Early 1900s comparison of elemental, solar, and stellar spectra]]
Astronomy is an ancient science, long separated from the study of terrestrial physics. In the [[Aristotle|Aristotelian]] worldview, bodies in the sky appeared to be unchanging [[Celestial spheres|spheres]] whose only motion was uniform motion in a circle, while the earthly world was the realm which underwent [[On Generation and Corruption|growth and decay]] and in which natural motion was in a straight line and ended when the moving object reached its [[Telos|goal]]. Consequently, it was held that the celestial region was made of a fundamentally different kind of matter from that found in the terrestrial sphere; either [[Fire (classical element)|Fire]] as maintained by [[Plato]], or [[Aether (classical element)|Aether]] as maintained by [[Aristotle#Physics|Aristotle]].<ref>{{cite book | last = Lloyd | first = G. E. R. | author-link = G. E. R. Lloyd | title = Aristotle: The Growth and Structure of His Thought | publisher = Cambridge University Press | year = 1968 | location = Cambridge | pages = [https://archive.org/details/aristotlegrowths0000lloy/page/134 134–135] | url =https://archive.org/details/aristotlegrowths0000lloy| url-access = registration | isbn = 978-0-521-09456-6}}</ref><ref>{{cite book | last = Cornford | first = Francis MacDonald | author-link = F. M. Cornford | title = Plato's Cosmology: The ''Timaeus'' of Plato translated, with a running commentary | publisher = Bobbs Merrill Co | date = c. 1957 | orig-year = 1937 | location = Indianapolis | page = 118}}</ref>
During the 17th century, natural philosophers such as [[Galileo]],<ref>{{Citation | last = Galilei | first = Galileo | author-link = Galileo Galilei | editor-last = Van Helden | editor-first = Albert | publication-date = 1989 | title = Sidereus Nuncius or The Sidereal Messenger | publisher = University of Chicago Press | location = Chicago | pages = 21, 47 | isbn = 978-0-226-27903-9 | date = 1989-04-15 }}</ref> [[Descartes]],<ref>{{Cite encyclopedia |author=Edward Slowik |title=Descartes' Physics |url=http://plato.stanford.edu/entries/descartes-physics/ |encyclopedia=[[Stanford Encyclopedia of Philosophy]] |date=2013 |orig-year=2005 |access-date=2015-07-18}}</ref> and [[Isaac Newton|Newton]]<ref>{{Citation | last = Westfall | first = Richard S. | author-link = Richard S. Westfall | publication-date = 1980 | title = Never at Rest: A Biography of Isaac Newton | publisher = Cambridge University Press | location = Cambridge | pages = [https://archive.org/details/neveratrestbiogr00west/page/731 731–732] | isbn = 978-0-521-27435-7 | date = 1983-04-29 | url-access = registration | url = https://archive.org/details/neveratrestbiogr00west/page/731 }}</ref> began to maintain that the celestial and terrestrial regions were made of similar kinds of material and were subject to the same [[Physical law|natural laws]].<ref name = Burtt/> Their challenge was that the tools had not yet been invented with which to prove these assertions.<ref>{{Cite journal |author=Ladislav Kvasz |title=Galileo, Descartes, and Newton – Founders of the Language of Physics |url=http://www.physics.sk/aps/pubs/2012/aps-12-06/aps-12-06.pdf |publisher=Institute of Philosophy, [[Academy of Sciences of the Czech Republic]] |date=2013 |access-date=2015-07-18}}</ref>
For much of the nineteenth century, astronomical research was focused on the routine work of measuring the positions and computing the motions of astronomical objects.<ref>{{Citation | last = Case | first = Stephen | date = 2015 | title = 'Land-marks of the universe': John Herschel against the background of positional astronomy | journal = Annals of Science | volume = 72 | issue = 4 | pages = 417–434 | doi = 10.1080/00033790.2015.1034588 | pmid = 26221834 | quote = The great majority of astronomers working in the early nineteenth century were not interested in stars as physical objects. Far from being bodies with physical properties to be investigated, the stars were seen as markers measured in order to construct an accurate, detailed and precise background against which solar, lunar and planetary motions could be charted, primarily for terrestrial applications.|bibcode = 2015AnSci..72..417C | doi-access = free }}</ref><ref>{{Citation | last = Donnelly | first = Kevin | date = September 2014 | title = On the boredom of science: positional astronomy in the nineteenth century | journal = The British Journal for the History of Science | volume = 47 | issue = 3 | pages = 479–503 | doi = 10.1017/S0007087413000915 | s2cid = 146382057 | url = https://zenodo.org/record/999531 }}</ref> A new astronomy, soon to be called astrophysics, began to emerge when [[William Hyde Wollaston]] and [[Joseph von Fraunhofer]] independently discovered that, when decomposing the light from the Sun, a multitude of [[Fraunhofer lines|dark lines]] (regions where there was less or no light) were observed in the [[Visible spectrum|spectrum]].<ref>{{cite book | last=Hearnshaw|first=J.B. | title=The analysis of starlight | date=1986 | publisher=Cambridge University Press | location=Cambridge | isbn=978-0-521-39916-6 | pages=23–29}}</ref> By 1860 the physicist, [[Gustav Kirchhoff]], and the chemist, [[Robert Bunsen]], had demonstrated that the [[Absorption spectroscopy#Absorption spectrum|dark lines]] in the solar spectrum corresponded to [[Emission spectrum|bright lines]] in the spectra of known gases, specific lines corresponding to unique [[chemical element]]s.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff |title=Ueber die Fraunhofer'schen Linien | journal=Annalen der Physik | volume=185 |issue=1 | pages=148–150 | date=1860 | bibcode = 1860AnP...185..148K | doi=10.1002/andp.18601850115| url = https://zenodo.org/record/1423666 }}</ref> Kirchhoff deduced that the dark lines in the solar spectrum are caused by [[absorption (optics)|absorption]] by [[chemical elements]] in the Solar atmosphere.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff | title=Ueber das Verhältniss zwischen dem Emissionsvermögen und dem Absorptionsvermögen der Körper für Wärme und Licht |journal=Annalen der Physik |volume=185 | issue=2 | pages=275–301 | date=1860 | bibcode = 1860AnP...185..275K | doi=10.1002/andp.18601850205| url=https://zenodo.org/record/1423668 | doi-access=free }}</ref> In this way it was proved that the chemical elements found in the Sun and stars were also found on Earth.
Among those who extended the study of solar and stellar spectra was [[Norman Lockyer]], who in 1868 detected radiant, as well as dark lines in solar spectra. Working with chemist [[Edward Frankland]] to investigate the spectra of elements at various temperatures and pressures, he could not associate a yellow line in the solar spectrum with any known elements. He thus claimed the line represented a new element, which was called [[helium]], after the Greek [[Helios]], the Sun personified.<ref>{{citation | last = Cortie | first = A. L. | title = Sir Norman Lockyer, 1836 – 1920 | journal = The Astrophysical Journal | year = 1921 | volume = 53 | pages = 233–248 | bibcode = 1921ApJ....53..233C | doi=10.1086/142602}}</ref><ref>{{Citation | last = Jensen | first = William B.|author1-link=William B. Jensen | title = Why Helium Ends in "-ium" | journal = Journal of Chemical Education | volume = 81 | issue = 7 | pages = 944–945 | year = 2004 | url = http://www.che.uc.edu/jensen/W.%20B.%20Jensen/Reprints/115.%20Helium.pdf | doi=10.1021/ed081p944 | bibcode = 2004JChEd..81..944J }}</ref>
In 1885, [[Edward C. Pickering]] undertook an ambitious program of stellar spectral classification at [[Harvard College Observatory]], in which a team of [[Harvard Computers|woman computers]], notably [[Williamina Fleming]], [[Antonia Maury]], and [[Annie Jump Cannon]], classified the spectra recorded on photographic plates. By 1890, a catalog of over 10,000 stars had been prepared that grouped them into thirteen spectral types. Following Pickering's vision, by 1924 Cannon expanded the [[Henry Draper Catalogue|catalog]] to nine volumes and over a quarter of a million stars, developing the [[Stellar classification#Harvard spectral classification|Harvard Classification Scheme]] which was accepted for worldwide use in 1922.<ref>{{Citation|last1=Hetherington |first1=Norriss S. |last2=McCray |first2=W. Patrick |author2-link=W. Patrick McCray |editor-last=Weart |editor-first=Spencer R. |editor-link=Spencer R. Weart |title=Spectroscopy and the Birth of Astrophysics |publisher=American Institute of Physics, Center for the History of Physics |url=https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |access-date=July 19, 2015 |url-status=dead |archive-url=https://web.archive.org/web/20150907133751/https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |archive-date=September 7, 2015 }}</ref>
In 1895, [[George Ellery Hale]] and [[James E. Keeler]], along with a group of ten associate editors from Europe and the United States,<ref name = Hale1895>{{Citation | last = Hale | first = George Ellery | title = The Astrophysical Journal | author-link = George Ellery Hale | journal = The Astrophysical Journal | volume = 1 | issue = 1 | pages = 80–84 | bibcode = 1895ApJ.....1...80H | doi = 10.1086/140011| year = 1895 }}</ref> established [[The Astrophysical Journal|''The Astrophysical Journal: An International Review of Spectroscopy and Astronomical Physics'']].<ref>{{List journal | journal = The Astrophysical Journal | volume = 1 | issue = 1 }}</ref> It was intended that the journal would fill the gap between journals in astronomy and physics, providing a venue for publication of articles on astronomical applications of the spectroscope; on laboratory research closely allied to astronomical physics, including wavelength determinations of metallic and gaseous spectra and experiments on radiation and absorption; on theories of the Sun, Moon, planets, comets, meteors, and nebulae; and on instrumentation for telescopes and laboratories.<ref name = Hale1895/>
Around 1920, following the discovery of the [[Hertzsprung–Russell diagram]] still used as the basis for classifying stars and their evolution, [[Arthur Eddington]] anticipated the discovery and mechanism of [[nuclear fusion]] processes in [[star]]s, in his paper ''The Internal Constitution of the Stars''.<ref name=eddington> {{ Citation | last = Eddington | first = A. S. | author-link = Arthur Eddington | date = October 1920 | title = The Internal Constitution of the Stars | journal = The Scientific Monthly | volume = 11 | issue = 4 | pages = 297–303 | doi = 10.1126/science.52.1341.233 | jstor = 6491 | pmid = 17747682 | bibcode = 1920Sci....52..233E | url = https://zenodo.org/record/1429642 }}</ref><ref name=eddington2>{{cite journal | bibcode = 1916MNRAS..77...16E | title = On the radiative equilibrium of the stars | journal=Monthly Notices of the Royal Astronomical Society | volume=77 | pages=16–35 | last1=Eddington|first1=A. S. | author-link = Arthur Eddington | year=1916 | doi=10.1093/mnras/77.1.16| doi-access=free }}</ref> At that time, the source of stellar energy was a complete mystery; Eddington correctly speculated that the source was [[nuclear fusion|fusion]] of hydrogen into helium, liberating enormous energy according to Einstein's equation ''E = mc<sup>2</sup>''. This was a particularly remarkable development since at that time fusion and thermonuclear energy, and even that stars are largely composed of [[hydrogen]] (see [[metallicity]]), had not yet been discovered.<ref>{{Cite book|title=Fusion|last1=McCracken|editor-last2=Stott|editor-first2=Peter|editor-last=McCracken|editor-first=Garry|last2=Stott|first2=Peter|first1=Garry|url=http://www.sciencedirect.com/science/article/pii/B9780123846563000027|language=en|doi=10.1016/b978-0-12-384656-3.00002-7|pages=13|isbn=978-0-12-384656-3|location=Boston|date=2013-01-01|publisher=Academic Press|quote=Eddington had realized that there would be a mass loss if four hydrogen atoms combined to form a single helium atom. Einstein’s equivalence of mass and energy led directly to the suggestion that this could be the long-sought process that produces the energy in the stars! It was an inspired guess, all the more remarkable because the structure of the nucleus and the mechanisms of these reactions were not fully understood.|edition=Second}}</ref>
In 1925 Cecilia Helena Payne (later [[Cecilia Payne-Gaposchkin]]) wrote an influential doctoral dissertation at [[Radcliffe College]], in which she applied ionization theory to stellar atmospheres to relate the spectral classes to the temperature of stars.<ref>{{citation |last=Payne |first=C. H. |year=1925 |title=Stellar Atmospheres; A Contribution to the Observational Study of High Temperature in the Reversing Layers of Stars |type=PhD Thesis |publisher=[[Radcliffe College]] | location = Cambridge, Massachusetts | publication-date = 1925 |bibcode=1925PhDT.........1P }}</ref> Most significantly, she discovered that hydrogen and helium were the principal components of stars. Despite Eddington's suggestion, this discovery was so unexpected that her dissertation readers convinced her to modify the conclusion before publication. However, later research confirmed her discovery.<ref>{{citation | last = Haramundanis | first = Katherine | editor-last = Hockey | editor-first = Thomas | editor2-last = Trimble | editor2-first = Virginia | editor2-link = Virginia Louise Trimble | editor3-last = Williams | editor3-first = Thomas R. | title = Biographical Encyclopedia of Astronomers | chapter = Payne-Gaposchkin [Payne], Cecilia Helena | access-date = July 19, 2015 |year=2007 | chapter-url=https://books.google.com/books?id=t-BF1CHkc50C | pages=876–878 | publisher = Springer | location = New York | isbn = 978-0-387-30400-7 }}</ref>
By the end of the 20th century, studies of astronomical spectra had expanded to cover wavelengths extending from radio waves through optical, x-ray, and gamma wavelengths.<ref>{{cite conference |mode=cs2 |last1=Biermann |first1=Peter L. |last2=Falcke |first2=Heino |author2-link=Heino Falcke |editor-last=Panvini |editor-first=Robert S. |editor2-last=Weiler |editor2-first=Thomas J. |date=1998 |book-title=Fundamental particles and interactions: Frontiers in contemporary physics an international lecture and workshop series. AIP Conference Proceedings |title=Frontiers of Astrophysics: Workshop Summary |volume=423 |publisher=American Institute of Physics |pages=236–248 |isbn=1-56396-725-1 |bibcode=1998AIPC..423..236B |doi=10.1063/1.55085|arxiv=astro-ph/9711066 }}</ref> In the 21st century, it further expanded to include observations based on [[gravitational waves]].
==Observational astrophysics==
[[Image:N 63A- Chandra and Hubble - Heic0507f.tif|thumb|right|200px|Supernova remnant LMC N 63A imaged in x-ray (blue), optical (green) and radio (red) wavelengths. The X-ray glow is from material heated to about ten million degrees Celsius by a shock wave generated by the supernova explosion.]]
[[Observational astronomy]] is a division of the astronomical science that is concerned with recording and interpreting data, in contrast with [[theoretical astrophysics]], which is mainly concerned with finding out the measurable implications of physical [[model (abstract)|models]]. It is the practice of observing [[celestial object]]s by using [[telescope]]s and other astronomical apparatus.
The majority of astrophysical observations are made using the [[electromagnetic spectrum]].
* [[Radio astronomy]] studies radiation with a [[wavelength]] greater than a few millimeters. Example areas of study are [[radio waves]], usually emitted by cold objects such as [[interstellar gas]] and dust clouds; the cosmic microwave background radiation which is the [[redshift]]ed light from the [[Big Bang]]; [[pulsar]]s, which were first detected at [[microwave]] frequencies. The study of these waves requires very large [[radio telescope]]s.
* [[Infrared astronomy]] studies radiation with a wavelength that is too long to be visible to the naked eye but is shorter than radio waves. Infrared observations are usually made with telescopes similar to the familiar [[optical]] telescopes. Objects colder than stars (such as planets) are normally studied at infrared frequencies.
* [[Optical astronomy]] was the earliest kind of astronomy. Telescopes paired with a [[charge-coupled device]] or [[spectroscope]]s are the most common instruments used. The Earth's [[atmosphere]] interferes somewhat with optical observations, so [[adaptive optics]] and [[space telescope]]s are used to obtain the highest possible image quality. In this wavelength range, stars are highly visible, and many chemical spectra can be observed to study the chemical composition of stars, galaxies, and [[nebula]]e.
* [[Ultraviolet]], [[X-ray astronomy|X-ray]] and [[gamma ray astronomy]] study very energetic processes such as [[binary pulsar]]s, [[black hole]]s, [[magnetar]]s, and many others. These kinds of radiation do not penetrate the Earth's atmosphere well. There are two methods in use to observe this part of the electromagnetic spectrum—[[space-based telescope]]s and ground-based [[imaging air Cherenkov telescope]]s (IACT). Examples of [[Observatory|Observatories]] of the first type are [[RXTE]], the [[Chandra X-ray Observatory]] and the [[Compton Gamma Ray Observatory]]. Examples of IACTs are the [[High Energy Stereoscopic System]] (H.E.S.S.) and the [[MAGIC (telescope)|MAGIC]] telescope.
Other than electromagnetic radiation, few things may be observed from the Earth that originate from great distances. A few [[gravitational wave]] observatories have been constructed, but gravitational waves are extremely difficult to detect. [[Neutrino]] observatories have also been built, primarily to study our Sun. Cosmic rays consisting of very high-energy particles can be observed hitting the Earth's atmosphere.
Observations can also vary in their time scale. Most optical observations take minutes to hours, so phenomena that change faster than this cannot readily be observed. However, historical data on some objects is available, spanning [[century|centuries]] or [[millennia]]. On the other hand, radio observations may look at events on a millisecond timescale ([[millisecond pulsar]]s) or combine years of data ([[Rotation-powered pulsar|pulsar deceleration]] studies). The information obtained from these different timescales is very different.
The study of our very own Sun has a special place in observational astrophysics. Due to the tremendous distance of all other stars, the Sun can be observed in a kind of detail unparalleled by any other star. Our understanding of our own Sun serves as a guide to our understanding of other stars.
The topic of how stars change, or stellar evolution, is often modeled by placing the varieties of star types in their respective positions on the [[Hertzsprung–Russell diagram]], which can be viewed as representing the state of a stellar object, from birth to destruction.
==Theoretical astrophysics==
{{see also|Theoretical astronomy}}
Theoretical astrophysicists use a wide variety of tools which include [[mathematical model|analytical models]] (for example, [[polytrope]]s to approximate the behaviors of a star) and [[computation]]al [[Numerical analysis|numerical simulations]]. Each has some advantages. Analytical models of a process are generally better for giving insight into the heart of what is going on. Numerical models can reveal the existence of phenomena and effects that would otherwise not be seen.<ref>{{Citation |first=H. |last=Roth |title=A Slowly Contracting or Expanding Fluid Sphere and its Stability |journal=[[Physical Review]] |volume=39 |issue=3 |pages=525–529 |year=1932 |doi=10.1103/PhysRev.39.525 |bibcode = 1932PhRv...39..525R }}</ref><ref>{{Citation |first=A.S. |last=Eddington |title=Internal Constitution of the Stars |journal=Science |location=New York |publisher=Cambridge University Press |orig-year=1926 |year=1988 |volume=52 |issue=1341 |pages=233–240 |doi=10.1126/science.52.1341.233 |isbn=978-0-521-33708-3 |pmid=17747682 |bibcode=1920Sci....52..233E |url=https://zenodo.org/record/1429642 }}</ref>
Theorists in astrophysics endeavor to create theoretical models and figure out the observational consequences of those models. This helps allow observers to look for data that can refute a model or help in choosing between several alternate or conflicting models.
Theorists also try to generate or modify models to take into account new data. In the case of an inconsistency, the general tendency is to try to make minimal modifications to the model to fit the data. In some cases, a large amount of inconsistent data over time may lead to total abandonment of a model.
Topics studied by theoretical astrophysicists include stellar dynamics and evolution; galaxy formation and evolution; magnetohydrodynamics; large-scale structure of matter in the universe; origin of cosmic rays; general relativity and physical cosmology, including [[string theory|string]] cosmology and astroparticle physics. Astrophysical relativity serves as a tool to gauge the properties of large-scale structures for which gravitation plays a significant role in physical phenomena investigated and as the basis for [[black hole]] (''astro'')physics and the study of [[gravitational waves]].
Some widely accepted and studied theories and models in astrophysics, now included in the [[Lambda-CDM model]], are the [[Big Bang]], [[cosmic inflation]], dark matter, dark energy and fundamental theories of physics.
== Popularization ==
The roots of astrophysics can be found in the seventeenth century emergence of a unified physics, in which the same laws applied to the celestial and terrestrial realms.<ref name = Burtt>{{Citation | last = Burtt | first = Edwin Arthur | author-link = Edwin Arthur Burtt | publication-date = 2003 | orig-year = First published 1924 | title = The Metaphysical Foundations of Modern Science | edition = second revised | publisher = Dover Publications | location = Mineola, NY | pages = 30, 41, 241–2 | isbn = 978-0-486-42551-1 | url = https://books.google.com/books?id=G9WBMa1Rz_kC | year = 2003 }}</ref> There were scientists who were qualified in both physics and astronomy who laid the firm foundation for the current science of astrophysics. In modern times, students continue to be drawn to astrophysics due to its popularization by the [[Royal Astronomical Society]] and notable [[Science education|educators]] such as prominent professors [[Lawrence Krauss]], [[Subrahmanyan Chandrasekhar]], [[Stephen Hawking]], [[Hubert Reeves]], [[Carl Sagan]], [[Neil deGrasse Tyson]] and [[Patrick Moore]]. The efforts of the early, late, and present scientists continue to attract young people to study the history and science of astrophysics.<ref>{{Cite web |author=D. Mark Manley |title=Famous Astronomers and Astrophysicists |url=http://cnr2.kent.edu/~manley/astronomers.html |publisher=[[Kent State University]] |date=2012 |access-date=2015-07-17}}</ref><ref>{{Cite web |author=The science.ca team |title=Hubert Reeves – Astronomy, Astrophysics and Space Science |url=http://www.science.ca/scientists/scientistprofile.php?pID=213 |publisher=GCS Research Society |date=2015 |access-date=2015-07-17}}</ref><ref>{{Cite web |title=Neil deGrasse Tyson |url=http://www.haydenplanetarium.org/tyson/ |publisher=[[Hayden Planetarium]] |date=2015 |access-date=2015-07-17}}</ref>
==See also==
{{cols|colwidth=21em}}
* [[Astrochemistry]]
* [[List of astronomical observatories|Astronomical observatories]]
* [[Astronomical spectroscopy]]
* [[Astroparticle physics]]
* [[Gravitational-wave astronomy]]
* [[Hertzsprung–Russell diagram]]
* [[High-energy astronomy]]
* [[List of important publications in physics#Astrophysics|Important publications in astrophysics]]
* [[List of astronomers]] (includes astrophysicists)
* [[Neutrino astronomy]] (future prospects)
* [[Timeline of gravitational physics and relativity]]
* [[Timeline of knowledge about galaxies, clusters of galaxies, and large-scale structure]]
* [[Timeline of white dwarfs, neutron stars, and supernovae]]
{{colend}}
==References==
{{Reflist}}
==Further reading==
* {{Citation | last = Longair | first = Malcolm S. | author-link = Malcolm S. Longair | title = The Cosmic Century: A History of Astrophysics and Cosmology | place = Cambridge | publisher = Cambridge University Press | year = 2006 | isbn = 978-0-521-47436-8 | url-access = registration | url = https://archive.org/details/cosmiccenturyhis0000long }}
* [http://www.scholarpedia.org/article/Encyclopedia:Astrophysics Astrophysics] [[Scholarpedia]] Expert articles
==External links==
{{Wikibooks|Astrophysics}}
{{Library resources box|onlinebooks=yes}}
* [http://www.aanda.org/ ''Astronomy and Astrophysics'', a European Journal]
* [http://iopscience.iop.org/0004-637X/ ''Astrophysical Journal'']
* [http://www.aip.org/history/cosmology/index.htm Cosmic Journey: A History of Scientific Cosmology] from the American Institute of Physics
* [http://www.worldscinet.com/ijmpd/ijmpd.shtml ''International Journal of Modern Physics D''] from [[World Scientific]]
* [http://www.scienceresourceworld.com/publications/journals/astronomy_journals.html List and directory of peer-reviewed Astronomy / Astrophysics Journals]
* [http://www.astro.ucla.edu/~wright/cosmolog.htm Ned Wright's Cosmology Tutorial, UCLA]
{{Physics-footer}}
{{Astronomy subfields}}
{{Astronomy navbox}}
{{Portal bar|Physics|Astronomy|Stars|Spaceflight|Outer space|Solar System}}
{{Authority control}}
[[Category:Astrophysics| ]]
[[Category:Astronomical sub-disciplines]]
bd2c54352b5f33382b25fe37da4e112ea4e9afdc
50
49
2022-07-08T17:20:09Z
SpaceMan
2
/* External links */
wikitext
text/x-wiki
{{short description|Branch of astronomy}}
{{About|the use of physics to determine the nature of astronomical objects|the use of physics to determine their positions and motions|Celestial mechanics|the physical study of the largest-scale structures of the universe|Physical cosmology|the journal|Astrophysics (journal)}}
{{TopicTOC-Physics}}
'''Astrophysics''' is a science that employs the methods and principles of [[physics]] and [[chemistry]] in the study of [[astronomical object]]s and phenomena.<ref>{{cite book |title=Astrophysics in a Nutshell |first=Dan |last=Maoz |date=23 February 2016 |publisher=Princeton University Press |pages=272 |isbn=9781400881178 |url=https://www.google.com/books/edition/Astrophysics_in_a_Nutshell/bmBeCwAAQBAJ?hl=en&gbpv=1&dq=%22astrophysics+is%22&pg=PA1&printsec=frontcover}}</ref><ref>{{cite web | title=astrophysics | publisher=Merriam-Webster, Incorporated | url=http://www.merriam-webster.com/dictionary/astrophysics | access-date=2011-05-22 | archive-url= https://web.archive.org/web/20110610085146/http://www.merriam-webster.com/dictionary/astrophysics| archive-date= 10 June 2011 | url-status= live}}</ref> As one of the founders of the discipline said, Astrophysics "seeks to ascertain the nature of the heavenly bodies, rather than their positions or motions in space–''what'' they are, rather than ''where'' they are."<ref>{{Citation | last = Keeler | first = James E. | author-link = James E. Keeler | title = The Importance of Astrophysical Research and the Relation of Astrophysics to the Other Physical Sciences | journal = The Astrophysical Journal | volume = 6 | issue = 4 | pages = 271–288 | date = November 1897 | bibcode = 1897ApJ.....6..271K |doi = 10.1086/140401 | pmid = 17796068 }}</ref> Among the subjects studied are the [[Sun]], other [[star]]s, [[galaxy|galaxies]], [[extrasolar planet]]s, the [[interstellar medium]] and the [[cosmic microwave background]].<ref name="nasa.gov">{{cite web|url=https://science.nasa.gov/astrophysics/focus-areas/|title=Focus Areas – NASA Science|work=nasa.gov}}</ref><ref>{{cite encyclopedia|url=https://www.britannica.com/EBchecked/topic/40047/astronomy|title=astronomy|encyclopedia=Encyclopædia Britannica}}</ref> Emissions from these objects are examined across all parts of the [[electromagnetic spectrum]], and the properties examined include [[luminosity]], [[density]], [[temperature]], and [[chemistry|chemical]] composition. Because astrophysics is a very broad subject, ''astrophysicists'' apply concepts and methods from many disciplines of physics and chemistry, including [[classical mechanics]], [[electromagnetism]], [[statistical mechanics]], [[thermodynamics]], [[quantum mechanics]], [[theory of relativity|relativity]], [[nuclear physics|nuclear]] and [[particle physics]], and [[atomic, molecular, and optical physics|atomic and molecular physics]].
In practice, modern astronomical research often involves a substantial amount of work in the realms of [[Theoretical physics|theoretical]] and observational physics. Some areas of study for astrophysicists include their attempts to determine the properties of [[dark matter]], [[dark energy]], [[black holes]], and other [[celestial bodies]]; and the [[Cosmogony|origin]] and [[ultimate fate of the universe]].<ref name="nasa.gov"/> Topics also studied by theoretical astrophysicists include [[Formation and evolution of the Solar System|Solar System formation and evolution]]; [[stellar dynamics]] and [[Stellar evolution|evolution]]; [[galaxy formation and evolution]]; [[magnetohydrodynamics]]; [[large-scale structure of the universe|large-scale structure]] of [[matter]] in the universe; origin of [[cosmic ray]]s; [[general relativity]], [[special relativity]], [[quantum cosmology|quantum]] and [[physical cosmology]], including [[string theory|string]] cosmology and [[astroparticle physics]].
==History==
[[Image:NIEdot362.jpg|thumb|left|200px|Early 1900s comparison of elemental, solar, and stellar spectra]]
Astronomy is an ancient science, long separated from the study of terrestrial physics. In the [[Aristotle|Aristotelian]] worldview, bodies in the sky appeared to be unchanging [[Celestial spheres|spheres]] whose only motion was uniform motion in a circle, while the earthly world was the realm which underwent [[On Generation and Corruption|growth and decay]] and in which natural motion was in a straight line and ended when the moving object reached its [[Telos|goal]]. Consequently, it was held that the celestial region was made of a fundamentally different kind of matter from that found in the terrestrial sphere; either [[Fire (classical element)|Fire]] as maintained by [[Plato]], or [[Aether (classical element)|Aether]] as maintained by [[Aristotle#Physics|Aristotle]].<ref>{{cite book | last = Lloyd | first = G. E. R. | author-link = G. E. R. Lloyd | title = Aristotle: The Growth and Structure of His Thought | publisher = Cambridge University Press | year = 1968 | location = Cambridge | pages = [https://archive.org/details/aristotlegrowths0000lloy/page/134 134–135] | url =https://archive.org/details/aristotlegrowths0000lloy| url-access = registration | isbn = 978-0-521-09456-6}}</ref><ref>{{cite book | last = Cornford | first = Francis MacDonald | author-link = F. M. Cornford | title = Plato's Cosmology: The ''Timaeus'' of Plato translated, with a running commentary | publisher = Bobbs Merrill Co | date = c. 1957 | orig-year = 1937 | location = Indianapolis | page = 118}}</ref>
During the 17th century, natural philosophers such as [[Galileo]],<ref>{{Citation | last = Galilei | first = Galileo | author-link = Galileo Galilei | editor-last = Van Helden | editor-first = Albert | publication-date = 1989 | title = Sidereus Nuncius or The Sidereal Messenger | publisher = University of Chicago Press | location = Chicago | pages = 21, 47 | isbn = 978-0-226-27903-9 | date = 1989-04-15 }}</ref> [[Descartes]],<ref>{{Cite encyclopedia |author=Edward Slowik |title=Descartes' Physics |url=http://plato.stanford.edu/entries/descartes-physics/ |encyclopedia=[[Stanford Encyclopedia of Philosophy]] |date=2013 |orig-year=2005 |access-date=2015-07-18}}</ref> and [[Isaac Newton|Newton]]<ref>{{Citation | last = Westfall | first = Richard S. | author-link = Richard S. Westfall | publication-date = 1980 | title = Never at Rest: A Biography of Isaac Newton | publisher = Cambridge University Press | location = Cambridge | pages = [https://archive.org/details/neveratrestbiogr00west/page/731 731–732] | isbn = 978-0-521-27435-7 | date = 1983-04-29 | url-access = registration | url = https://archive.org/details/neveratrestbiogr00west/page/731 }}</ref> began to maintain that the celestial and terrestrial regions were made of similar kinds of material and were subject to the same [[Physical law|natural laws]].<ref name = Burtt/> Their challenge was that the tools had not yet been invented with which to prove these assertions.<ref>{{Cite journal |author=Ladislav Kvasz |title=Galileo, Descartes, and Newton – Founders of the Language of Physics |url=http://www.physics.sk/aps/pubs/2012/aps-12-06/aps-12-06.pdf |publisher=Institute of Philosophy, [[Academy of Sciences of the Czech Republic]] |date=2013 |access-date=2015-07-18}}</ref>
For much of the nineteenth century, astronomical research was focused on the routine work of measuring the positions and computing the motions of astronomical objects.<ref>{{Citation | last = Case | first = Stephen | date = 2015 | title = 'Land-marks of the universe': John Herschel against the background of positional astronomy | journal = Annals of Science | volume = 72 | issue = 4 | pages = 417–434 | doi = 10.1080/00033790.2015.1034588 | pmid = 26221834 | quote = The great majority of astronomers working in the early nineteenth century were not interested in stars as physical objects. Far from being bodies with physical properties to be investigated, the stars were seen as markers measured in order to construct an accurate, detailed and precise background against which solar, lunar and planetary motions could be charted, primarily for terrestrial applications.|bibcode = 2015AnSci..72..417C | doi-access = free }}</ref><ref>{{Citation | last = Donnelly | first = Kevin | date = September 2014 | title = On the boredom of science: positional astronomy in the nineteenth century | journal = The British Journal for the History of Science | volume = 47 | issue = 3 | pages = 479–503 | doi = 10.1017/S0007087413000915 | s2cid = 146382057 | url = https://zenodo.org/record/999531 }}</ref> A new astronomy, soon to be called astrophysics, began to emerge when [[William Hyde Wollaston]] and [[Joseph von Fraunhofer]] independently discovered that, when decomposing the light from the Sun, a multitude of [[Fraunhofer lines|dark lines]] (regions where there was less or no light) were observed in the [[Visible spectrum|spectrum]].<ref>{{cite book | last=Hearnshaw|first=J.B. | title=The analysis of starlight | date=1986 | publisher=Cambridge University Press | location=Cambridge | isbn=978-0-521-39916-6 | pages=23–29}}</ref> By 1860 the physicist, [[Gustav Kirchhoff]], and the chemist, [[Robert Bunsen]], had demonstrated that the [[Absorption spectroscopy#Absorption spectrum|dark lines]] in the solar spectrum corresponded to [[Emission spectrum|bright lines]] in the spectra of known gases, specific lines corresponding to unique [[chemical element]]s.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff |title=Ueber die Fraunhofer'schen Linien | journal=Annalen der Physik | volume=185 |issue=1 | pages=148–150 | date=1860 | bibcode = 1860AnP...185..148K | doi=10.1002/andp.18601850115| url = https://zenodo.org/record/1423666 }}</ref> Kirchhoff deduced that the dark lines in the solar spectrum are caused by [[absorption (optics)|absorption]] by [[chemical elements]] in the Solar atmosphere.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff | title=Ueber das Verhältniss zwischen dem Emissionsvermögen und dem Absorptionsvermögen der Körper für Wärme und Licht |journal=Annalen der Physik |volume=185 | issue=2 | pages=275–301 | date=1860 | bibcode = 1860AnP...185..275K | doi=10.1002/andp.18601850205| url=https://zenodo.org/record/1423668 | doi-access=free }}</ref> In this way it was proved that the chemical elements found in the Sun and stars were also found on Earth.
Among those who extended the study of solar and stellar spectra was [[Norman Lockyer]], who in 1868 detected radiant, as well as dark lines in solar spectra. Working with chemist [[Edward Frankland]] to investigate the spectra of elements at various temperatures and pressures, he could not associate a yellow line in the solar spectrum with any known elements. He thus claimed the line represented a new element, which was called [[helium]], after the Greek [[Helios]], the Sun personified.<ref>{{citation | last = Cortie | first = A. L. | title = Sir Norman Lockyer, 1836 – 1920 | journal = The Astrophysical Journal | year = 1921 | volume = 53 | pages = 233–248 | bibcode = 1921ApJ....53..233C | doi=10.1086/142602}}</ref><ref>{{Citation | last = Jensen | first = William B.|author1-link=William B. Jensen | title = Why Helium Ends in "-ium" | journal = Journal of Chemical Education | volume = 81 | issue = 7 | pages = 944–945 | year = 2004 | url = http://www.che.uc.edu/jensen/W.%20B.%20Jensen/Reprints/115.%20Helium.pdf | doi=10.1021/ed081p944 | bibcode = 2004JChEd..81..944J }}</ref>
In 1885, [[Edward C. Pickering]] undertook an ambitious program of stellar spectral classification at [[Harvard College Observatory]], in which a team of [[Harvard Computers|woman computers]], notably [[Williamina Fleming]], [[Antonia Maury]], and [[Annie Jump Cannon]], classified the spectra recorded on photographic plates. By 1890, a catalog of over 10,000 stars had been prepared that grouped them into thirteen spectral types. Following Pickering's vision, by 1924 Cannon expanded the [[Henry Draper Catalogue|catalog]] to nine volumes and over a quarter of a million stars, developing the [[Stellar classification#Harvard spectral classification|Harvard Classification Scheme]] which was accepted for worldwide use in 1922.<ref>{{Citation|last1=Hetherington |first1=Norriss S. |last2=McCray |first2=W. Patrick |author2-link=W. Patrick McCray |editor-last=Weart |editor-first=Spencer R. |editor-link=Spencer R. Weart |title=Spectroscopy and the Birth of Astrophysics |publisher=American Institute of Physics, Center for the History of Physics |url=https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |access-date=July 19, 2015 |url-status=dead |archive-url=https://web.archive.org/web/20150907133751/https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |archive-date=September 7, 2015 }}</ref>
In 1895, [[George Ellery Hale]] and [[James E. Keeler]], along with a group of ten associate editors from Europe and the United States,<ref name = Hale1895>{{Citation | last = Hale | first = George Ellery | title = The Astrophysical Journal | author-link = George Ellery Hale | journal = The Astrophysical Journal | volume = 1 | issue = 1 | pages = 80–84 | bibcode = 1895ApJ.....1...80H | doi = 10.1086/140011| year = 1895 }}</ref> established [[The Astrophysical Journal|''The Astrophysical Journal: An International Review of Spectroscopy and Astronomical Physics'']].<ref>{{List journal | journal = The Astrophysical Journal | volume = 1 | issue = 1 }}</ref> It was intended that the journal would fill the gap between journals in astronomy and physics, providing a venue for publication of articles on astronomical applications of the spectroscope; on laboratory research closely allied to astronomical physics, including wavelength determinations of metallic and gaseous spectra and experiments on radiation and absorption; on theories of the Sun, Moon, planets, comets, meteors, and nebulae; and on instrumentation for telescopes and laboratories.<ref name = Hale1895/>
Around 1920, following the discovery of the [[Hertzsprung–Russell diagram]] still used as the basis for classifying stars and their evolution, [[Arthur Eddington]] anticipated the discovery and mechanism of [[nuclear fusion]] processes in [[star]]s, in his paper ''The Internal Constitution of the Stars''.<ref name=eddington> {{ Citation | last = Eddington | first = A. S. | author-link = Arthur Eddington | date = October 1920 | title = The Internal Constitution of the Stars | journal = The Scientific Monthly | volume = 11 | issue = 4 | pages = 297–303 | doi = 10.1126/science.52.1341.233 | jstor = 6491 | pmid = 17747682 | bibcode = 1920Sci....52..233E | url = https://zenodo.org/record/1429642 }}</ref><ref name=eddington2>{{cite journal | bibcode = 1916MNRAS..77...16E | title = On the radiative equilibrium of the stars | journal=Monthly Notices of the Royal Astronomical Society | volume=77 | pages=16–35 | last1=Eddington|first1=A. S. | author-link = Arthur Eddington | year=1916 | doi=10.1093/mnras/77.1.16| doi-access=free }}</ref> At that time, the source of stellar energy was a complete mystery; Eddington correctly speculated that the source was [[nuclear fusion|fusion]] of hydrogen into helium, liberating enormous energy according to Einstein's equation ''E = mc<sup>2</sup>''. This was a particularly remarkable development since at that time fusion and thermonuclear energy, and even that stars are largely composed of [[hydrogen]] (see [[metallicity]]), had not yet been discovered.<ref>{{Cite book|title=Fusion|last1=McCracken|editor-last2=Stott|editor-first2=Peter|editor-last=McCracken|editor-first=Garry|last2=Stott|first2=Peter|first1=Garry|url=http://www.sciencedirect.com/science/article/pii/B9780123846563000027|language=en|doi=10.1016/b978-0-12-384656-3.00002-7|pages=13|isbn=978-0-12-384656-3|location=Boston|date=2013-01-01|publisher=Academic Press|quote=Eddington had realized that there would be a mass loss if four hydrogen atoms combined to form a single helium atom. Einstein’s equivalence of mass and energy led directly to the suggestion that this could be the long-sought process that produces the energy in the stars! It was an inspired guess, all the more remarkable because the structure of the nucleus and the mechanisms of these reactions were not fully understood.|edition=Second}}</ref>
In 1925 Cecilia Helena Payne (later [[Cecilia Payne-Gaposchkin]]) wrote an influential doctoral dissertation at [[Radcliffe College]], in which she applied ionization theory to stellar atmospheres to relate the spectral classes to the temperature of stars.<ref>{{citation |last=Payne |first=C. H. |year=1925 |title=Stellar Atmospheres; A Contribution to the Observational Study of High Temperature in the Reversing Layers of Stars |type=PhD Thesis |publisher=[[Radcliffe College]] | location = Cambridge, Massachusetts | publication-date = 1925 |bibcode=1925PhDT.........1P }}</ref> Most significantly, she discovered that hydrogen and helium were the principal components of stars. Despite Eddington's suggestion, this discovery was so unexpected that her dissertation readers convinced her to modify the conclusion before publication. However, later research confirmed her discovery.<ref>{{citation | last = Haramundanis | first = Katherine | editor-last = Hockey | editor-first = Thomas | editor2-last = Trimble | editor2-first = Virginia | editor2-link = Virginia Louise Trimble | editor3-last = Williams | editor3-first = Thomas R. | title = Biographical Encyclopedia of Astronomers | chapter = Payne-Gaposchkin [Payne], Cecilia Helena | access-date = July 19, 2015 |year=2007 | chapter-url=https://books.google.com/books?id=t-BF1CHkc50C | pages=876–878 | publisher = Springer | location = New York | isbn = 978-0-387-30400-7 }}</ref>
By the end of the 20th century, studies of astronomical spectra had expanded to cover wavelengths extending from radio waves through optical, x-ray, and gamma wavelengths.<ref>{{cite conference |mode=cs2 |last1=Biermann |first1=Peter L. |last2=Falcke |first2=Heino |author2-link=Heino Falcke |editor-last=Panvini |editor-first=Robert S. |editor2-last=Weiler |editor2-first=Thomas J. |date=1998 |book-title=Fundamental particles and interactions: Frontiers in contemporary physics an international lecture and workshop series. AIP Conference Proceedings |title=Frontiers of Astrophysics: Workshop Summary |volume=423 |publisher=American Institute of Physics |pages=236–248 |isbn=1-56396-725-1 |bibcode=1998AIPC..423..236B |doi=10.1063/1.55085|arxiv=astro-ph/9711066 }}</ref> In the 21st century, it further expanded to include observations based on [[gravitational waves]].
==Observational astrophysics==
[[Image:N 63A- Chandra and Hubble - Heic0507f.tif|thumb|right|200px|Supernova remnant LMC N 63A imaged in x-ray (blue), optical (green) and radio (red) wavelengths. The X-ray glow is from material heated to about ten million degrees Celsius by a shock wave generated by the supernova explosion.]]
[[Observational astronomy]] is a division of the astronomical science that is concerned with recording and interpreting data, in contrast with [[theoretical astrophysics]], which is mainly concerned with finding out the measurable implications of physical [[model (abstract)|models]]. It is the practice of observing [[celestial object]]s by using [[telescope]]s and other astronomical apparatus.
The majority of astrophysical observations are made using the [[electromagnetic spectrum]].
* [[Radio astronomy]] studies radiation with a [[wavelength]] greater than a few millimeters. Example areas of study are [[radio waves]], usually emitted by cold objects such as [[interstellar gas]] and dust clouds; the cosmic microwave background radiation which is the [[redshift]]ed light from the [[Big Bang]]; [[pulsar]]s, which were first detected at [[microwave]] frequencies. The study of these waves requires very large [[radio telescope]]s.
* [[Infrared astronomy]] studies radiation with a wavelength that is too long to be visible to the naked eye but is shorter than radio waves. Infrared observations are usually made with telescopes similar to the familiar [[optical]] telescopes. Objects colder than stars (such as planets) are normally studied at infrared frequencies.
* [[Optical astronomy]] was the earliest kind of astronomy. Telescopes paired with a [[charge-coupled device]] or [[spectroscope]]s are the most common instruments used. The Earth's [[atmosphere]] interferes somewhat with optical observations, so [[adaptive optics]] and [[space telescope]]s are used to obtain the highest possible image quality. In this wavelength range, stars are highly visible, and many chemical spectra can be observed to study the chemical composition of stars, galaxies, and [[nebula]]e.
* [[Ultraviolet]], [[X-ray astronomy|X-ray]] and [[gamma ray astronomy]] study very energetic processes such as [[binary pulsar]]s, [[black hole]]s, [[magnetar]]s, and many others. These kinds of radiation do not penetrate the Earth's atmosphere well. There are two methods in use to observe this part of the electromagnetic spectrum—[[space-based telescope]]s and ground-based [[imaging air Cherenkov telescope]]s (IACT). Examples of [[Observatory|Observatories]] of the first type are [[RXTE]], the [[Chandra X-ray Observatory]] and the [[Compton Gamma Ray Observatory]]. Examples of IACTs are the [[High Energy Stereoscopic System]] (H.E.S.S.) and the [[MAGIC (telescope)|MAGIC]] telescope.
Other than electromagnetic radiation, few things may be observed from the Earth that originate from great distances. A few [[gravitational wave]] observatories have been constructed, but gravitational waves are extremely difficult to detect. [[Neutrino]] observatories have also been built, primarily to study our Sun. Cosmic rays consisting of very high-energy particles can be observed hitting the Earth's atmosphere.
Observations can also vary in their time scale. Most optical observations take minutes to hours, so phenomena that change faster than this cannot readily be observed. However, historical data on some objects is available, spanning [[century|centuries]] or [[millennia]]. On the other hand, radio observations may look at events on a millisecond timescale ([[millisecond pulsar]]s) or combine years of data ([[Rotation-powered pulsar|pulsar deceleration]] studies). The information obtained from these different timescales is very different.
The study of our very own Sun has a special place in observational astrophysics. Due to the tremendous distance of all other stars, the Sun can be observed in a kind of detail unparalleled by any other star. Our understanding of our own Sun serves as a guide to our understanding of other stars.
The topic of how stars change, or stellar evolution, is often modeled by placing the varieties of star types in their respective positions on the [[Hertzsprung–Russell diagram]], which can be viewed as representing the state of a stellar object, from birth to destruction.
==Theoretical astrophysics==
{{see also|Theoretical astronomy}}
Theoretical astrophysicists use a wide variety of tools which include [[mathematical model|analytical models]] (for example, [[polytrope]]s to approximate the behaviors of a star) and [[computation]]al [[Numerical analysis|numerical simulations]]. Each has some advantages. Analytical models of a process are generally better for giving insight into the heart of what is going on. Numerical models can reveal the existence of phenomena and effects that would otherwise not be seen.<ref>{{Citation |first=H. |last=Roth |title=A Slowly Contracting or Expanding Fluid Sphere and its Stability |journal=[[Physical Review]] |volume=39 |issue=3 |pages=525–529 |year=1932 |doi=10.1103/PhysRev.39.525 |bibcode = 1932PhRv...39..525R }}</ref><ref>{{Citation |first=A.S. |last=Eddington |title=Internal Constitution of the Stars |journal=Science |location=New York |publisher=Cambridge University Press |orig-year=1926 |year=1988 |volume=52 |issue=1341 |pages=233–240 |doi=10.1126/science.52.1341.233 |isbn=978-0-521-33708-3 |pmid=17747682 |bibcode=1920Sci....52..233E |url=https://zenodo.org/record/1429642 }}</ref>
Theorists in astrophysics endeavor to create theoretical models and figure out the observational consequences of those models. This helps allow observers to look for data that can refute a model or help in choosing between several alternate or conflicting models.
Theorists also try to generate or modify models to take into account new data. In the case of an inconsistency, the general tendency is to try to make minimal modifications to the model to fit the data. In some cases, a large amount of inconsistent data over time may lead to total abandonment of a model.
Topics studied by theoretical astrophysicists include stellar dynamics and evolution; galaxy formation and evolution; magnetohydrodynamics; large-scale structure of matter in the universe; origin of cosmic rays; general relativity and physical cosmology, including [[string theory|string]] cosmology and astroparticle physics. Astrophysical relativity serves as a tool to gauge the properties of large-scale structures for which gravitation plays a significant role in physical phenomena investigated and as the basis for [[black hole]] (''astro'')physics and the study of [[gravitational waves]].
Some widely accepted and studied theories and models in astrophysics, now included in the [[Lambda-CDM model]], are the [[Big Bang]], [[cosmic inflation]], dark matter, dark energy and fundamental theories of physics.
== Popularization ==
The roots of astrophysics can be found in the seventeenth century emergence of a unified physics, in which the same laws applied to the celestial and terrestrial realms.<ref name = Burtt>{{Citation | last = Burtt | first = Edwin Arthur | author-link = Edwin Arthur Burtt | publication-date = 2003 | orig-year = First published 1924 | title = The Metaphysical Foundations of Modern Science | edition = second revised | publisher = Dover Publications | location = Mineola, NY | pages = 30, 41, 241–2 | isbn = 978-0-486-42551-1 | url = https://books.google.com/books?id=G9WBMa1Rz_kC | year = 2003 }}</ref> There were scientists who were qualified in both physics and astronomy who laid the firm foundation for the current science of astrophysics. In modern times, students continue to be drawn to astrophysics due to its popularization by the [[Royal Astronomical Society]] and notable [[Science education|educators]] such as prominent professors [[Lawrence Krauss]], [[Subrahmanyan Chandrasekhar]], [[Stephen Hawking]], [[Hubert Reeves]], [[Carl Sagan]], [[Neil deGrasse Tyson]] and [[Patrick Moore]]. The efforts of the early, late, and present scientists continue to attract young people to study the history and science of astrophysics.<ref>{{Cite web |author=D. Mark Manley |title=Famous Astronomers and Astrophysicists |url=http://cnr2.kent.edu/~manley/astronomers.html |publisher=[[Kent State University]] |date=2012 |access-date=2015-07-17}}</ref><ref>{{Cite web |author=The science.ca team |title=Hubert Reeves – Astronomy, Astrophysics and Space Science |url=http://www.science.ca/scientists/scientistprofile.php?pID=213 |publisher=GCS Research Society |date=2015 |access-date=2015-07-17}}</ref><ref>{{Cite web |title=Neil deGrasse Tyson |url=http://www.haydenplanetarium.org/tyson/ |publisher=[[Hayden Planetarium]] |date=2015 |access-date=2015-07-17}}</ref>
==See also==
{{cols|colwidth=21em}}
* [[Astrochemistry]]
* [[List of astronomical observatories|Astronomical observatories]]
* [[Astronomical spectroscopy]]
* [[Astroparticle physics]]
* [[Gravitational-wave astronomy]]
* [[Hertzsprung–Russell diagram]]
* [[High-energy astronomy]]
* [[List of important publications in physics#Astrophysics|Important publications in astrophysics]]
* [[List of astronomers]] (includes astrophysicists)
* [[Neutrino astronomy]] (future prospects)
* [[Timeline of gravitational physics and relativity]]
* [[Timeline of knowledge about galaxies, clusters of galaxies, and large-scale structure]]
* [[Timeline of white dwarfs, neutron stars, and supernovae]]
{{colend}}
==References==
{{Reflist}}
==Further reading==
* {{Citation | last = Longair | first = Malcolm S. | author-link = Malcolm S. Longair | title = The Cosmic Century: A History of Astrophysics and Cosmology | place = Cambridge | publisher = Cambridge University Press | year = 2006 | isbn = 978-0-521-47436-8 | url-access = registration | url = https://archive.org/details/cosmiccenturyhis0000long }}
* [http://www.scholarpedia.org/article/Encyclopedia:Astrophysics Astrophysics] [[Scholarpedia]] Expert articles
==External links==
{{Wikibooks|Astrophysics}}
{{Library resources box|onlinebooks=yes}}
* [http://www.aanda.org/ ''Astronomy and Astrophysics'', a European Journal]
* [http://iopscience.iop.org/0004-637X/ ''Astrophysical Journal'']
* [http://www.aip.org/history/cosmology/index.htm Cosmic Journey: A History of Scientific Cosmology] from the American Institute of Physics
* [http://www.worldscinet.com/ijmpd/ijmpd.shtml ''International Journal of Modern Physics D''] from [[World Scientific]]
* [http://www.scienceresourceworld.com/publications/journals/astronomy_journals.html List and directory of peer-reviewed Astronomy / Astrophysics Journals]
* [http://www.astro.ucla.edu/~wright/cosmolog.htm Ned Wright's Cosmology Tutorial, UCLA]
e5badca507ad3ccdb40c5cd0bc4e6e251b56be53
51
50
2022-07-08T17:21:09Z
SpaceMan
2
Protected "[[Astrophysics]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
{{short description|Branch of astronomy}}
{{About|the use of physics to determine the nature of astronomical objects|the use of physics to determine their positions and motions|Celestial mechanics|the physical study of the largest-scale structures of the universe|Physical cosmology|the journal|Astrophysics (journal)}}
{{TopicTOC-Physics}}
'''Astrophysics''' is a science that employs the methods and principles of [[physics]] and [[chemistry]] in the study of [[astronomical object]]s and phenomena.<ref>{{cite book |title=Astrophysics in a Nutshell |first=Dan |last=Maoz |date=23 February 2016 |publisher=Princeton University Press |pages=272 |isbn=9781400881178 |url=https://www.google.com/books/edition/Astrophysics_in_a_Nutshell/bmBeCwAAQBAJ?hl=en&gbpv=1&dq=%22astrophysics+is%22&pg=PA1&printsec=frontcover}}</ref><ref>{{cite web | title=astrophysics | publisher=Merriam-Webster, Incorporated | url=http://www.merriam-webster.com/dictionary/astrophysics | access-date=2011-05-22 | archive-url= https://web.archive.org/web/20110610085146/http://www.merriam-webster.com/dictionary/astrophysics| archive-date= 10 June 2011 | url-status= live}}</ref> As one of the founders of the discipline said, Astrophysics "seeks to ascertain the nature of the heavenly bodies, rather than their positions or motions in space–''what'' they are, rather than ''where'' they are."<ref>{{Citation | last = Keeler | first = James E. | author-link = James E. Keeler | title = The Importance of Astrophysical Research and the Relation of Astrophysics to the Other Physical Sciences | journal = The Astrophysical Journal | volume = 6 | issue = 4 | pages = 271–288 | date = November 1897 | bibcode = 1897ApJ.....6..271K |doi = 10.1086/140401 | pmid = 17796068 }}</ref> Among the subjects studied are the [[Sun]], other [[star]]s, [[galaxy|galaxies]], [[extrasolar planet]]s, the [[interstellar medium]] and the [[cosmic microwave background]].<ref name="nasa.gov">{{cite web|url=https://science.nasa.gov/astrophysics/focus-areas/|title=Focus Areas – NASA Science|work=nasa.gov}}</ref><ref>{{cite encyclopedia|url=https://www.britannica.com/EBchecked/topic/40047/astronomy|title=astronomy|encyclopedia=Encyclopædia Britannica}}</ref> Emissions from these objects are examined across all parts of the [[electromagnetic spectrum]], and the properties examined include [[luminosity]], [[density]], [[temperature]], and [[chemistry|chemical]] composition. Because astrophysics is a very broad subject, ''astrophysicists'' apply concepts and methods from many disciplines of physics and chemistry, including [[classical mechanics]], [[electromagnetism]], [[statistical mechanics]], [[thermodynamics]], [[quantum mechanics]], [[theory of relativity|relativity]], [[nuclear physics|nuclear]] and [[particle physics]], and [[atomic, molecular, and optical physics|atomic and molecular physics]].
In practice, modern astronomical research often involves a substantial amount of work in the realms of [[Theoretical physics|theoretical]] and observational physics. Some areas of study for astrophysicists include their attempts to determine the properties of [[dark matter]], [[dark energy]], [[black holes]], and other [[celestial bodies]]; and the [[Cosmogony|origin]] and [[ultimate fate of the universe]].<ref name="nasa.gov"/> Topics also studied by theoretical astrophysicists include [[Formation and evolution of the Solar System|Solar System formation and evolution]]; [[stellar dynamics]] and [[Stellar evolution|evolution]]; [[galaxy formation and evolution]]; [[magnetohydrodynamics]]; [[large-scale structure of the universe|large-scale structure]] of [[matter]] in the universe; origin of [[cosmic ray]]s; [[general relativity]], [[special relativity]], [[quantum cosmology|quantum]] and [[physical cosmology]], including [[string theory|string]] cosmology and [[astroparticle physics]].
==History==
[[Image:NIEdot362.jpg|thumb|left|200px|Early 1900s comparison of elemental, solar, and stellar spectra]]
Astronomy is an ancient science, long separated from the study of terrestrial physics. In the [[Aristotle|Aristotelian]] worldview, bodies in the sky appeared to be unchanging [[Celestial spheres|spheres]] whose only motion was uniform motion in a circle, while the earthly world was the realm which underwent [[On Generation and Corruption|growth and decay]] and in which natural motion was in a straight line and ended when the moving object reached its [[Telos|goal]]. Consequently, it was held that the celestial region was made of a fundamentally different kind of matter from that found in the terrestrial sphere; either [[Fire (classical element)|Fire]] as maintained by [[Plato]], or [[Aether (classical element)|Aether]] as maintained by [[Aristotle#Physics|Aristotle]].<ref>{{cite book | last = Lloyd | first = G. E. R. | author-link = G. E. R. Lloyd | title = Aristotle: The Growth and Structure of His Thought | publisher = Cambridge University Press | year = 1968 | location = Cambridge | pages = [https://archive.org/details/aristotlegrowths0000lloy/page/134 134–135] | url =https://archive.org/details/aristotlegrowths0000lloy| url-access = registration | isbn = 978-0-521-09456-6}}</ref><ref>{{cite book | last = Cornford | first = Francis MacDonald | author-link = F. M. Cornford | title = Plato's Cosmology: The ''Timaeus'' of Plato translated, with a running commentary | publisher = Bobbs Merrill Co | date = c. 1957 | orig-year = 1937 | location = Indianapolis | page = 118}}</ref>
During the 17th century, natural philosophers such as [[Galileo]],<ref>{{Citation | last = Galilei | first = Galileo | author-link = Galileo Galilei | editor-last = Van Helden | editor-first = Albert | publication-date = 1989 | title = Sidereus Nuncius or The Sidereal Messenger | publisher = University of Chicago Press | location = Chicago | pages = 21, 47 | isbn = 978-0-226-27903-9 | date = 1989-04-15 }}</ref> [[Descartes]],<ref>{{Cite encyclopedia |author=Edward Slowik |title=Descartes' Physics |url=http://plato.stanford.edu/entries/descartes-physics/ |encyclopedia=[[Stanford Encyclopedia of Philosophy]] |date=2013 |orig-year=2005 |access-date=2015-07-18}}</ref> and [[Isaac Newton|Newton]]<ref>{{Citation | last = Westfall | first = Richard S. | author-link = Richard S. Westfall | publication-date = 1980 | title = Never at Rest: A Biography of Isaac Newton | publisher = Cambridge University Press | location = Cambridge | pages = [https://archive.org/details/neveratrestbiogr00west/page/731 731–732] | isbn = 978-0-521-27435-7 | date = 1983-04-29 | url-access = registration | url = https://archive.org/details/neveratrestbiogr00west/page/731 }}</ref> began to maintain that the celestial and terrestrial regions were made of similar kinds of material and were subject to the same [[Physical law|natural laws]].<ref name = Burtt/> Their challenge was that the tools had not yet been invented with which to prove these assertions.<ref>{{Cite journal |author=Ladislav Kvasz |title=Galileo, Descartes, and Newton – Founders of the Language of Physics |url=http://www.physics.sk/aps/pubs/2012/aps-12-06/aps-12-06.pdf |publisher=Institute of Philosophy, [[Academy of Sciences of the Czech Republic]] |date=2013 |access-date=2015-07-18}}</ref>
For much of the nineteenth century, astronomical research was focused on the routine work of measuring the positions and computing the motions of astronomical objects.<ref>{{Citation | last = Case | first = Stephen | date = 2015 | title = 'Land-marks of the universe': John Herschel against the background of positional astronomy | journal = Annals of Science | volume = 72 | issue = 4 | pages = 417–434 | doi = 10.1080/00033790.2015.1034588 | pmid = 26221834 | quote = The great majority of astronomers working in the early nineteenth century were not interested in stars as physical objects. Far from being bodies with physical properties to be investigated, the stars were seen as markers measured in order to construct an accurate, detailed and precise background against which solar, lunar and planetary motions could be charted, primarily for terrestrial applications.|bibcode = 2015AnSci..72..417C | doi-access = free }}</ref><ref>{{Citation | last = Donnelly | first = Kevin | date = September 2014 | title = On the boredom of science: positional astronomy in the nineteenth century | journal = The British Journal for the History of Science | volume = 47 | issue = 3 | pages = 479–503 | doi = 10.1017/S0007087413000915 | s2cid = 146382057 | url = https://zenodo.org/record/999531 }}</ref> A new astronomy, soon to be called astrophysics, began to emerge when [[William Hyde Wollaston]] and [[Joseph von Fraunhofer]] independently discovered that, when decomposing the light from the Sun, a multitude of [[Fraunhofer lines|dark lines]] (regions where there was less or no light) were observed in the [[Visible spectrum|spectrum]].<ref>{{cite book | last=Hearnshaw|first=J.B. | title=The analysis of starlight | date=1986 | publisher=Cambridge University Press | location=Cambridge | isbn=978-0-521-39916-6 | pages=23–29}}</ref> By 1860 the physicist, [[Gustav Kirchhoff]], and the chemist, [[Robert Bunsen]], had demonstrated that the [[Absorption spectroscopy#Absorption spectrum|dark lines]] in the solar spectrum corresponded to [[Emission spectrum|bright lines]] in the spectra of known gases, specific lines corresponding to unique [[chemical element]]s.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff |title=Ueber die Fraunhofer'schen Linien | journal=Annalen der Physik | volume=185 |issue=1 | pages=148–150 | date=1860 | bibcode = 1860AnP...185..148K | doi=10.1002/andp.18601850115| url = https://zenodo.org/record/1423666 }}</ref> Kirchhoff deduced that the dark lines in the solar spectrum are caused by [[absorption (optics)|absorption]] by [[chemical elements]] in the Solar atmosphere.<ref>{{citation | last = Kirchhoff | first = Gustav | author-link = Gustav Kirchhoff | title=Ueber das Verhältniss zwischen dem Emissionsvermögen und dem Absorptionsvermögen der Körper für Wärme und Licht |journal=Annalen der Physik |volume=185 | issue=2 | pages=275–301 | date=1860 | bibcode = 1860AnP...185..275K | doi=10.1002/andp.18601850205| url=https://zenodo.org/record/1423668 | doi-access=free }}</ref> In this way it was proved that the chemical elements found in the Sun and stars were also found on Earth.
Among those who extended the study of solar and stellar spectra was [[Norman Lockyer]], who in 1868 detected radiant, as well as dark lines in solar spectra. Working with chemist [[Edward Frankland]] to investigate the spectra of elements at various temperatures and pressures, he could not associate a yellow line in the solar spectrum with any known elements. He thus claimed the line represented a new element, which was called [[helium]], after the Greek [[Helios]], the Sun personified.<ref>{{citation | last = Cortie | first = A. L. | title = Sir Norman Lockyer, 1836 – 1920 | journal = The Astrophysical Journal | year = 1921 | volume = 53 | pages = 233–248 | bibcode = 1921ApJ....53..233C | doi=10.1086/142602}}</ref><ref>{{Citation | last = Jensen | first = William B.|author1-link=William B. Jensen | title = Why Helium Ends in "-ium" | journal = Journal of Chemical Education | volume = 81 | issue = 7 | pages = 944–945 | year = 2004 | url = http://www.che.uc.edu/jensen/W.%20B.%20Jensen/Reprints/115.%20Helium.pdf | doi=10.1021/ed081p944 | bibcode = 2004JChEd..81..944J }}</ref>
In 1885, [[Edward C. Pickering]] undertook an ambitious program of stellar spectral classification at [[Harvard College Observatory]], in which a team of [[Harvard Computers|woman computers]], notably [[Williamina Fleming]], [[Antonia Maury]], and [[Annie Jump Cannon]], classified the spectra recorded on photographic plates. By 1890, a catalog of over 10,000 stars had been prepared that grouped them into thirteen spectral types. Following Pickering's vision, by 1924 Cannon expanded the [[Henry Draper Catalogue|catalog]] to nine volumes and over a quarter of a million stars, developing the [[Stellar classification#Harvard spectral classification|Harvard Classification Scheme]] which was accepted for worldwide use in 1922.<ref>{{Citation|last1=Hetherington |first1=Norriss S. |last2=McCray |first2=W. Patrick |author2-link=W. Patrick McCray |editor-last=Weart |editor-first=Spencer R. |editor-link=Spencer R. Weart |title=Spectroscopy and the Birth of Astrophysics |publisher=American Institute of Physics, Center for the History of Physics |url=https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |access-date=July 19, 2015 |url-status=dead |archive-url=https://web.archive.org/web/20150907133751/https://www.aip.org/history/cosmology/tools/tools-spectroscopy.htm |archive-date=September 7, 2015 }}</ref>
In 1895, [[George Ellery Hale]] and [[James E. Keeler]], along with a group of ten associate editors from Europe and the United States,<ref name = Hale1895>{{Citation | last = Hale | first = George Ellery | title = The Astrophysical Journal | author-link = George Ellery Hale | journal = The Astrophysical Journal | volume = 1 | issue = 1 | pages = 80–84 | bibcode = 1895ApJ.....1...80H | doi = 10.1086/140011| year = 1895 }}</ref> established [[The Astrophysical Journal|''The Astrophysical Journal: An International Review of Spectroscopy and Astronomical Physics'']].<ref>{{List journal | journal = The Astrophysical Journal | volume = 1 | issue = 1 }}</ref> It was intended that the journal would fill the gap between journals in astronomy and physics, providing a venue for publication of articles on astronomical applications of the spectroscope; on laboratory research closely allied to astronomical physics, including wavelength determinations of metallic and gaseous spectra and experiments on radiation and absorption; on theories of the Sun, Moon, planets, comets, meteors, and nebulae; and on instrumentation for telescopes and laboratories.<ref name = Hale1895/>
Around 1920, following the discovery of the [[Hertzsprung–Russell diagram]] still used as the basis for classifying stars and their evolution, [[Arthur Eddington]] anticipated the discovery and mechanism of [[nuclear fusion]] processes in [[star]]s, in his paper ''The Internal Constitution of the Stars''.<ref name=eddington> {{ Citation | last = Eddington | first = A. S. | author-link = Arthur Eddington | date = October 1920 | title = The Internal Constitution of the Stars | journal = The Scientific Monthly | volume = 11 | issue = 4 | pages = 297–303 | doi = 10.1126/science.52.1341.233 | jstor = 6491 | pmid = 17747682 | bibcode = 1920Sci....52..233E | url = https://zenodo.org/record/1429642 }}</ref><ref name=eddington2>{{cite journal | bibcode = 1916MNRAS..77...16E | title = On the radiative equilibrium of the stars | journal=Monthly Notices of the Royal Astronomical Society | volume=77 | pages=16–35 | last1=Eddington|first1=A. S. | author-link = Arthur Eddington | year=1916 | doi=10.1093/mnras/77.1.16| doi-access=free }}</ref> At that time, the source of stellar energy was a complete mystery; Eddington correctly speculated that the source was [[nuclear fusion|fusion]] of hydrogen into helium, liberating enormous energy according to Einstein's equation ''E = mc<sup>2</sup>''. This was a particularly remarkable development since at that time fusion and thermonuclear energy, and even that stars are largely composed of [[hydrogen]] (see [[metallicity]]), had not yet been discovered.<ref>{{Cite book|title=Fusion|last1=McCracken|editor-last2=Stott|editor-first2=Peter|editor-last=McCracken|editor-first=Garry|last2=Stott|first2=Peter|first1=Garry|url=http://www.sciencedirect.com/science/article/pii/B9780123846563000027|language=en|doi=10.1016/b978-0-12-384656-3.00002-7|pages=13|isbn=978-0-12-384656-3|location=Boston|date=2013-01-01|publisher=Academic Press|quote=Eddington had realized that there would be a mass loss if four hydrogen atoms combined to form a single helium atom. Einstein’s equivalence of mass and energy led directly to the suggestion that this could be the long-sought process that produces the energy in the stars! It was an inspired guess, all the more remarkable because the structure of the nucleus and the mechanisms of these reactions were not fully understood.|edition=Second}}</ref>
In 1925 Cecilia Helena Payne (later [[Cecilia Payne-Gaposchkin]]) wrote an influential doctoral dissertation at [[Radcliffe College]], in which she applied ionization theory to stellar atmospheres to relate the spectral classes to the temperature of stars.<ref>{{citation |last=Payne |first=C. H. |year=1925 |title=Stellar Atmospheres; A Contribution to the Observational Study of High Temperature in the Reversing Layers of Stars |type=PhD Thesis |publisher=[[Radcliffe College]] | location = Cambridge, Massachusetts | publication-date = 1925 |bibcode=1925PhDT.........1P }}</ref> Most significantly, she discovered that hydrogen and helium were the principal components of stars. Despite Eddington's suggestion, this discovery was so unexpected that her dissertation readers convinced her to modify the conclusion before publication. However, later research confirmed her discovery.<ref>{{citation | last = Haramundanis | first = Katherine | editor-last = Hockey | editor-first = Thomas | editor2-last = Trimble | editor2-first = Virginia | editor2-link = Virginia Louise Trimble | editor3-last = Williams | editor3-first = Thomas R. | title = Biographical Encyclopedia of Astronomers | chapter = Payne-Gaposchkin [Payne], Cecilia Helena | access-date = July 19, 2015 |year=2007 | chapter-url=https://books.google.com/books?id=t-BF1CHkc50C | pages=876–878 | publisher = Springer | location = New York | isbn = 978-0-387-30400-7 }}</ref>
By the end of the 20th century, studies of astronomical spectra had expanded to cover wavelengths extending from radio waves through optical, x-ray, and gamma wavelengths.<ref>{{cite conference |mode=cs2 |last1=Biermann |first1=Peter L. |last2=Falcke |first2=Heino |author2-link=Heino Falcke |editor-last=Panvini |editor-first=Robert S. |editor2-last=Weiler |editor2-first=Thomas J. |date=1998 |book-title=Fundamental particles and interactions: Frontiers in contemporary physics an international lecture and workshop series. AIP Conference Proceedings |title=Frontiers of Astrophysics: Workshop Summary |volume=423 |publisher=American Institute of Physics |pages=236–248 |isbn=1-56396-725-1 |bibcode=1998AIPC..423..236B |doi=10.1063/1.55085|arxiv=astro-ph/9711066 }}</ref> In the 21st century, it further expanded to include observations based on [[gravitational waves]].
==Observational astrophysics==
[[Image:N 63A- Chandra and Hubble - Heic0507f.tif|thumb|right|200px|Supernova remnant LMC N 63A imaged in x-ray (blue), optical (green) and radio (red) wavelengths. The X-ray glow is from material heated to about ten million degrees Celsius by a shock wave generated by the supernova explosion.]]
[[Observational astronomy]] is a division of the astronomical science that is concerned with recording and interpreting data, in contrast with [[theoretical astrophysics]], which is mainly concerned with finding out the measurable implications of physical [[model (abstract)|models]]. It is the practice of observing [[celestial object]]s by using [[telescope]]s and other astronomical apparatus.
The majority of astrophysical observations are made using the [[electromagnetic spectrum]].
* [[Radio astronomy]] studies radiation with a [[wavelength]] greater than a few millimeters. Example areas of study are [[radio waves]], usually emitted by cold objects such as [[interstellar gas]] and dust clouds; the cosmic microwave background radiation which is the [[redshift]]ed light from the [[Big Bang]]; [[pulsar]]s, which were first detected at [[microwave]] frequencies. The study of these waves requires very large [[radio telescope]]s.
* [[Infrared astronomy]] studies radiation with a wavelength that is too long to be visible to the naked eye but is shorter than radio waves. Infrared observations are usually made with telescopes similar to the familiar [[optical]] telescopes. Objects colder than stars (such as planets) are normally studied at infrared frequencies.
* [[Optical astronomy]] was the earliest kind of astronomy. Telescopes paired with a [[charge-coupled device]] or [[spectroscope]]s are the most common instruments used. The Earth's [[atmosphere]] interferes somewhat with optical observations, so [[adaptive optics]] and [[space telescope]]s are used to obtain the highest possible image quality. In this wavelength range, stars are highly visible, and many chemical spectra can be observed to study the chemical composition of stars, galaxies, and [[nebula]]e.
* [[Ultraviolet]], [[X-ray astronomy|X-ray]] and [[gamma ray astronomy]] study very energetic processes such as [[binary pulsar]]s, [[black hole]]s, [[magnetar]]s, and many others. These kinds of radiation do not penetrate the Earth's atmosphere well. There are two methods in use to observe this part of the electromagnetic spectrum—[[space-based telescope]]s and ground-based [[imaging air Cherenkov telescope]]s (IACT). Examples of [[Observatory|Observatories]] of the first type are [[RXTE]], the [[Chandra X-ray Observatory]] and the [[Compton Gamma Ray Observatory]]. Examples of IACTs are the [[High Energy Stereoscopic System]] (H.E.S.S.) and the [[MAGIC (telescope)|MAGIC]] telescope.
Other than electromagnetic radiation, few things may be observed from the Earth that originate from great distances. A few [[gravitational wave]] observatories have been constructed, but gravitational waves are extremely difficult to detect. [[Neutrino]] observatories have also been built, primarily to study our Sun. Cosmic rays consisting of very high-energy particles can be observed hitting the Earth's atmosphere.
Observations can also vary in their time scale. Most optical observations take minutes to hours, so phenomena that change faster than this cannot readily be observed. However, historical data on some objects is available, spanning [[century|centuries]] or [[millennia]]. On the other hand, radio observations may look at events on a millisecond timescale ([[millisecond pulsar]]s) or combine years of data ([[Rotation-powered pulsar|pulsar deceleration]] studies). The information obtained from these different timescales is very different.
The study of our very own Sun has a special place in observational astrophysics. Due to the tremendous distance of all other stars, the Sun can be observed in a kind of detail unparalleled by any other star. Our understanding of our own Sun serves as a guide to our understanding of other stars.
The topic of how stars change, or stellar evolution, is often modeled by placing the varieties of star types in their respective positions on the [[Hertzsprung–Russell diagram]], which can be viewed as representing the state of a stellar object, from birth to destruction.
==Theoretical astrophysics==
{{see also|Theoretical astronomy}}
Theoretical astrophysicists use a wide variety of tools which include [[mathematical model|analytical models]] (for example, [[polytrope]]s to approximate the behaviors of a star) and [[computation]]al [[Numerical analysis|numerical simulations]]. Each has some advantages. Analytical models of a process are generally better for giving insight into the heart of what is going on. Numerical models can reveal the existence of phenomena and effects that would otherwise not be seen.<ref>{{Citation |first=H. |last=Roth |title=A Slowly Contracting or Expanding Fluid Sphere and its Stability |journal=[[Physical Review]] |volume=39 |issue=3 |pages=525–529 |year=1932 |doi=10.1103/PhysRev.39.525 |bibcode = 1932PhRv...39..525R }}</ref><ref>{{Citation |first=A.S. |last=Eddington |title=Internal Constitution of the Stars |journal=Science |location=New York |publisher=Cambridge University Press |orig-year=1926 |year=1988 |volume=52 |issue=1341 |pages=233–240 |doi=10.1126/science.52.1341.233 |isbn=978-0-521-33708-3 |pmid=17747682 |bibcode=1920Sci....52..233E |url=https://zenodo.org/record/1429642 }}</ref>
Theorists in astrophysics endeavor to create theoretical models and figure out the observational consequences of those models. This helps allow observers to look for data that can refute a model or help in choosing between several alternate or conflicting models.
Theorists also try to generate or modify models to take into account new data. In the case of an inconsistency, the general tendency is to try to make minimal modifications to the model to fit the data. In some cases, a large amount of inconsistent data over time may lead to total abandonment of a model.
Topics studied by theoretical astrophysicists include stellar dynamics and evolution; galaxy formation and evolution; magnetohydrodynamics; large-scale structure of matter in the universe; origin of cosmic rays; general relativity and physical cosmology, including [[string theory|string]] cosmology and astroparticle physics. Astrophysical relativity serves as a tool to gauge the properties of large-scale structures for which gravitation plays a significant role in physical phenomena investigated and as the basis for [[black hole]] (''astro'')physics and the study of [[gravitational waves]].
Some widely accepted and studied theories and models in astrophysics, now included in the [[Lambda-CDM model]], are the [[Big Bang]], [[cosmic inflation]], dark matter, dark energy and fundamental theories of physics.
== Popularization ==
The roots of astrophysics can be found in the seventeenth century emergence of a unified physics, in which the same laws applied to the celestial and terrestrial realms.<ref name = Burtt>{{Citation | last = Burtt | first = Edwin Arthur | author-link = Edwin Arthur Burtt | publication-date = 2003 | orig-year = First published 1924 | title = The Metaphysical Foundations of Modern Science | edition = second revised | publisher = Dover Publications | location = Mineola, NY | pages = 30, 41, 241–2 | isbn = 978-0-486-42551-1 | url = https://books.google.com/books?id=G9WBMa1Rz_kC | year = 2003 }}</ref> There were scientists who were qualified in both physics and astronomy who laid the firm foundation for the current science of astrophysics. In modern times, students continue to be drawn to astrophysics due to its popularization by the [[Royal Astronomical Society]] and notable [[Science education|educators]] such as prominent professors [[Lawrence Krauss]], [[Subrahmanyan Chandrasekhar]], [[Stephen Hawking]], [[Hubert Reeves]], [[Carl Sagan]], [[Neil deGrasse Tyson]] and [[Patrick Moore]]. The efforts of the early, late, and present scientists continue to attract young people to study the history and science of astrophysics.<ref>{{Cite web |author=D. Mark Manley |title=Famous Astronomers and Astrophysicists |url=http://cnr2.kent.edu/~manley/astronomers.html |publisher=[[Kent State University]] |date=2012 |access-date=2015-07-17}}</ref><ref>{{Cite web |author=The science.ca team |title=Hubert Reeves – Astronomy, Astrophysics and Space Science |url=http://www.science.ca/scientists/scientistprofile.php?pID=213 |publisher=GCS Research Society |date=2015 |access-date=2015-07-17}}</ref><ref>{{Cite web |title=Neil deGrasse Tyson |url=http://www.haydenplanetarium.org/tyson/ |publisher=[[Hayden Planetarium]] |date=2015 |access-date=2015-07-17}}</ref>
==See also==
{{cols|colwidth=21em}}
* [[Astrochemistry]]
* [[List of astronomical observatories|Astronomical observatories]]
* [[Astronomical spectroscopy]]
* [[Astroparticle physics]]
* [[Gravitational-wave astronomy]]
* [[Hertzsprung–Russell diagram]]
* [[High-energy astronomy]]
* [[List of important publications in physics#Astrophysics|Important publications in astrophysics]]
* [[List of astronomers]] (includes astrophysicists)
* [[Neutrino astronomy]] (future prospects)
* [[Timeline of gravitational physics and relativity]]
* [[Timeline of knowledge about galaxies, clusters of galaxies, and large-scale structure]]
* [[Timeline of white dwarfs, neutron stars, and supernovae]]
{{colend}}
==References==
{{Reflist}}
==Further reading==
* {{Citation | last = Longair | first = Malcolm S. | author-link = Malcolm S. Longair | title = The Cosmic Century: A History of Astrophysics and Cosmology | place = Cambridge | publisher = Cambridge University Press | year = 2006 | isbn = 978-0-521-47436-8 | url-access = registration | url = https://archive.org/details/cosmiccenturyhis0000long }}
* [http://www.scholarpedia.org/article/Encyclopedia:Astrophysics Astrophysics] [[Scholarpedia]] Expert articles
==External links==
{{Wikibooks|Astrophysics}}
{{Library resources box|onlinebooks=yes}}
* [http://www.aanda.org/ ''Astronomy and Astrophysics'', a European Journal]
* [http://iopscience.iop.org/0004-637X/ ''Astrophysical Journal'']
* [http://www.aip.org/history/cosmology/index.htm Cosmic Journey: A History of Scientific Cosmology] from the American Institute of Physics
* [http://www.worldscinet.com/ijmpd/ijmpd.shtml ''International Journal of Modern Physics D''] from [[World Scientific]]
* [http://www.scienceresourceworld.com/publications/journals/astronomy_journals.html List and directory of peer-reviewed Astronomy / Astrophysics Journals]
* [http://www.astro.ucla.edu/~wright/cosmolog.htm Ned Wright's Cosmology Tutorial, UCLA]
e5badca507ad3ccdb40c5cd0bc4e6e251b56be53
Template:Round
10
126
267
2022-07-09T01:53:46Z
Canopus >Neveselbert
0
safesubst
wikitext
text/x-wiki
<includeonly>{{safesubst<noinclude/>:#iferror:{{#expr:{{{2|0}}}}} |
{{main other|[[Category:Pages with bad rounding precision]]}}{{hid|Bad rounding here}}<!--
-->{{safesubst<noinclude/>:#invoke:Math|precision_format| {{{1}}} | 1-{{order of magnitude|{{{1}}}}} }}|
{{safesubst<noinclude/>:#invoke:Math|precision_format| {{{1}}} | {{{2|0}}}}}}}</includeonly><noinclude>
{{documentation}}
</noinclude>
9c2874586b74824fe1beb6830b56eabe7ad936ce
Template:Sky
10
140
295
2022-07-14T20:04:15Z
Canopus >TheDJ
0
avoid <p>
wikitext
text/x-wiki
<noinclude></noinclude><includeonly>{{#ifeq:{{{display|}}}|inline|<span class="sky-coordinates-inline plainlinks nourlexpansion">[[File:Jupiter and moon.png|20px|link=|Sky map]] [http://www.wikisky.org/?ra={{#expr:{{trim|{{{1}}}}}+{{trim|{{{2}}}}}/60+{{trim|{{{3}}}}}/3600}}&de={{#expr:{{trim|{{{4|+}}}}}{{trim|{{{5}}}}}+{{trim|{{{4|+}}}}}{{trim|{{{6}}}}}/60+{{trim|{{{4|+}}}}}{{trim|{{{7}}}}}/3600}}&zoom={{#expr:ln{{{8|100000}}}/ln10+1 round 0}}&show_grid=1&show_constellation_lines=1&show_constellation_boundaries=1&show_const_names=1&show_galaxies=1&img_source=IMG_all {{trim|{{{1}}}}}<sup>h</sup> {{trim|{{{2}}}}}<sup>m</sup> {{trim|{{{3}}}}}<sup>s</sup>, {{#ifeq:{{trim|{{{4}}}}}|-|−|{{trim|{{{4}}}}} }}{{trim|{{{5}}}}}° {{trim|{{{6}}}}}′ {{trim|{{{7}}}}}″]</span>|<indicator name="01-sky-coordinates"><templatestyles src="Template:Sky/styles.css" /><!--
This mostly repeats the previous statement, but i'm to lazy to write a lua module for it, try to keep it in sync --><span class="sky-coordinates-display plainlinks nourlexpansion">[[Celestial coordinate system|Coordinates]]: [[File:Jupiter and moon.png|20px|link=|Sky map]] [http://www.wikisky.org/?ra={{#expr:{{trim|{{{1}}}}}+{{trim|{{{2}}}}}/60+{{trim|{{{3}}}}}/3600}}&de={{#expr:{{trim|{{{4|+}}}}}{{trim|{{{5}}}}}+{{trim|{{{4|+}}}}}{{trim|{{{6}}}}}/60+{{trim|{{{4|+}}}}}{{trim|{{{7}}}}}/3600}}&zoom={{#expr:ln{{{8|100000}}}/ln10+1 round 0}}&show_grid=1&show_constellation_lines=1&show_constellation_boundaries=1&show_const_names=1&show_galaxies=1&img_source=IMG_all {{trim|{{{1}}}}}<sup>h</sup> {{trim|{{{2}}}}}<sup>m</sup> {{trim|{{{3}}}}}<sup>s</sup>, {{#ifeq:{{trim|{{{4}}}}}|-|−|{{trim|{{{4}}}}} }}{{trim|{{{5}}}}}° {{trim|{{{6}}}}}′ {{trim|{{{7}}}}}″]</span></indicator>
}}</includeonly><noinclude>{{documentation}}</noinclude>
0820a25c62d725441979785de033585a0ffa870e
Energy
0
25
53
52
2022-07-17T09:16:17Z
SpaceMan
2
1 revision imported: Energy
wikitext
text/x-wiki
Energy of a body is defined as the capacity or ability of the body to do [[Work]].
==Forms of energy==
===Mechanical energy===
It includes kinetic and potential energy.
'''Kinetic energy'''
The energy possessed by a body by the virtue of its motion is called kinetic energy. An object in motion has the ability to do work and hence possesses kinetic energy.
Examples of Kinetic Energy
(1) Wind possesses kinetic energy and can run wind mill.
(1) The kinetic energy of flowing water is used to generate electricity.
(ii) A bullet fired from a gun possesses kinetic energy and can penetrate a target.
Formula
Kinetic energy = 1/2 *mv²
Where m = mass and v² = velocity squared
'''Potential energy'''
The energy possessed by a body by the virtue of its position([[displacement]]) or its configuration (shape or size) is called potential energy. An object may have the capacity of doing work as a result of its position in a gravitational([[gravity]]) field, an electric field or a magnetic field. Potential energy may be positive or negative. Potential energy is often referred as stored energy.
Examples of Potential Energy
(1) The heavy ball of a demolition machine has potential energy when it is held at an elevated position.
(i) A stone lying on the ground has no energy so it cannot do any work. If this stone is lifted to the roof of a house, the work has been done in lifting this stone against the force of gravity. This
work gets stored up in the stone in the form of potential energy.
(ii) The water stored at height in a dam has potential energy. If it is allowed to fall, the falling water has the ability to rotate turbine to generate electricity.
(M) A stone resting on the edge of a cliff has potential energy due to its position in the earth's gravitational field. If it falls, the force of gravity which is equal to the stone's weight will act on it until it strikes the ground. The stone's potential energy is equal to the product of its weight and distance it can fall through.
(1) Elastic Potential Energy
The energy possessed by a body due to the change in its shape is called as elastic potential energy. The change in shape of the body can be brought by compressing, stretching or bending. For this change, some work has to be done. This work gets stored in the form of elastic potential energy. When this deformed body is released it regains its original position and potential energy is given out in some other form of energy.
(B)
"The gravitational potential energy of an object at a point above the ground is defined as the as the work done is raising it from the ground to that point against gravity without any [[acceleration]]"
Formula
Work (w) = Mass (M) * Gravity (g) * Displacement (S) or w = mg * s
Potential energy = mg * h
===Heat energy===
Heat can be defined as the form of energy that is transferred between two points due to the presence of a [[temperature]] difference between the two points. When water boils, it changes to steam. The steam possesses heat energy because it has the ability to do work such as to run stear engines, turbine etc. The heat produced by the burning of petrol in a car engine provides the energy needed to run the car.
===Nuclear energy===
The energy stored in the nucleus of an atom is called nuclear energy. The energy stored in the nuclei of atoms can be obtained by carrying out two types of nuclear reactions called nuclear fusion and nuclear fission.
c9ad0cf3f0a960b707ef98e06b087a2ec4630142
Kepler
0
26
55
54
2022-07-17T09:20:50Z
SpaceMan
2
1 revision imported: Johannes Kepler
wikitext
text/x-wiki
Johannes Kepler was a German [[astronomer]], [[mathematician]], [[astrologer]], natural philosopher and writer on music.[5] He is a key figure in the 17th-century Scientific Revolution, best known for his laws of planetary motion, and his books Astronomia nova, Harmonice Mundi, and Epitome Astronomiae Copernicanae. These works also provided one of the foundations for [[Isaac Newton]] theory of universal gravitation([[Gravity]]).
{| class="wikitable"
|+Facts
|-
|Born
|27 December 1571
Free Imperial City of Weil der Stadt, Holy Roman Empire
|-
|Died
|15 November 1630 (aged 58)
|-
|Nationality
|German
|-
|Known for
|[[Kepler's laws of planetary motion]]
Kepler conjecture
Rudolphine Tables
|-
|Fields
|[[Astronomy]], [[astrology]], [[mathematics]], natural philosophy
|}
3645e8bbf01a9572c47839bad9c98471c4335cf1
MediaWiki:Citizen-footer-desc
8
27
58
2022-07-17T09:26:28Z
SpaceMan
2
Created blank page
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Template:Odlist
10
164
343
2022-07-22T15:52:32Z
Canopus >Shāntián Tàiláng
0
wikitext
text/x-wiki
{{comma separated entries
<!-- Traditional/proper names, or exoplanet star designations -->
| {{{name<includeonly>|</includeonly>}}}
| {{{name2<includeonly>|</includeonly>}}}
| {{{name3<includeonly>|</includeonly>}}}
| {{{name4<includeonly>|</includeonly>}}}
| {{{name5<includeonly>|</includeonly>}}}
<!-- Bayer, Flamsteed, Gould, and variable star designations -->
| {{#if:{{{B|}}} |[[Bayer designation|{{{B}}}]]}}
| {{#if:{{{F|}}} |[[Flamsteed designation|{{{F}}}]]}}
| {{#if:{{{Gould|}}}|[[Gould designation|{{{Gould}}}]]}}
| {{#if:{{{V|}}} |[[Variable star designation|{{{V}}}]]}}
| {{#if:{{{NSV|}}} |[[New Catalogue of Suspected Variable Stars|NSV]] {{{NSV}}}}}
<!-- Commonly used designations like HD, HIP, HR -->
| {{#if:{{{AG|}}} |{{nowrap|[[Astronomische Gesellschaft Katalog|AG]]{{Str rep|{{{AG}}}|-|−}}}}}}
| {{#if:{{{BD<includeonly>|</includeonly>}}} |{{nowrap|[[Bonner Durchmusterung|BD]]{{Str rep|{{{BD}}}|-|−}}}}}}
| {{#if:{{{CD|}}} |{{nowrap|[[Cordoba Durchmusterung|CD]]{{Str rep|{{{CD}}}|-|−}}}}}}
| {{#if:{{{CP|}}} |{{nowrap|[[Cape Photographic Durchmusterung|CPD]]{{Str rep|{{{CP}}}|-|−}}}}}}
| {{#if:{{{CPD|}}} |{{nowrap|[[Cape Photographic Durchmusterung|CPD]]{{Str rep|{{{CPD}}}|-|−}}}}}}
| {{#if:{{{FK5|}}} |[[Fifth Fundamental Catalogue|FK5]] {{{FK5}}}}}
| {{#if:{{{Gaia DR1|}}} |{{nowrap|[[Star_catalogue#Gaia_Catalogue|Gaia DR1]] {{{Gaia DR1}}}}}}}
| {{#if:{{{Gaia DR2|}}} |{{nowrap|[[Star_catalogue#Gaia_Catalogue|Gaia DR2]] {{{Gaia DR2}}}}}}}
| {{#if:{{{GC|}}} |[[Boss General Catalogue|GC]] {{{GC}}}}}
| {{#if:{{{GJ<includeonly>|</includeonly>}}} |[[Gliese Catalogue of Nearby Stars|GJ]] {{{GJ}}}}}
| {{#if:{{{GJ2<includeonly>|</includeonly>}}} |GJ {{{GJ2}}}}}
| {{#if:{{{HD<includeonly>|</includeonly>}}} |[[Henry Draper Catalogue|HD]] {{{HD}}}}}
| {{#if:{{{HIP<includeonly>|</includeonly>}}} |[[Hipparcos Catalogue|HIP]] {{{HIP}}}}}
| {{#if:{{{HR<includeonly>|</includeonly>}}} |[[Harvard Revised catalogue|HR]] {{{HR}}}}}
| {{#if:{{{SAO<includeonly>|</includeonly>}}} |[[Smithsonian Astrophysical Observatory Star Catalog|SAO]] {{{SAO}}}}}
| {{#if:{{{PPM|}}} |[[Position and proper motion catalogue|PPM]] {{{PPM}}}}}
<!-- Double star catalogs -->
| {{#if:{{{ADS|}}} |[[Aitken Double Star Catalogue|ADS]] {{{ADS}}}}}
| {{#if:{{{CCDM|}}} |{{nowrap|[[Catalog of Components of Double and Multiple Stars|CCDM]] {{{CCDM}}}}}}}
| {{#if:{{{WDS<includeonly>|</includeonly>}}} |{{nowrap|[[Washington Double Star Catalog|WDS]] {{{WDS}}}}}}}
| {{#if:{{{DC|}}} |[[Discovery code|{{{DC}}}]]}}
<!-- Nearby/high-proper-motion star catalogues and the like-->
| {{#if:{{{AC|}}} |[[Carte du Ciel|AC]] {{{AC}}}}}
| {{#if:{{{BPM|}}} |[[Bruce Proper Motion survey|BPM]] {{{BPM}}}}}
| {{#if:{{{Ci 18|}}}|[[Cincinnati Observatory|Ci]] 18 {{{Ci 18}}}}}
| {{#if:{{{Ci 20|}}}|[[Cincinnati Observatory|Ci]] 20 {{{Ci 20}}}}}
| {{#if:{{{EGGR|}}} |[[Olin J. Eggen|EG]][[Jesse L. Greenstein|GR]] {{{EGGR}}}}}
| {{#if:{{{G|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G}}}}}}}
| {{#if:{{{G2|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G2}}}}}}}
| {{#if:{{{G3|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G3}}}}}}}
| {{#if:{{{L|}}} |[[Luyten|L]] {{{L}}}}}
| {{#if:{{{LAL|}}} |[[Histoire céleste française|LAL]] {{{LAL}}}}}
| {{#if:{{{LAWD|}}} |[[Luyten Atlas of White Dwarfs|LAWD]] {{{LAWD}}}}}
| {{#if:{{{LFT|}}} |[[Luyten Five-Tenths catalogue|LFT]] {{{LFT}}}}}
| {{#if:{{{LHS|}}} |[[Luyten Half-Second Catalogue|LHS]] {{{LHS}}}}}
| {{#if:{{{LP|}}} |[[Luyten-Palomar proper motion catalogue|LP]] {{{LP}}}}}
| {{#if:{{{LPM|}}} |[[Luyten Proper-Motion Catalogue|LPM]] {{{LPM}}}}}
| {{#if:{{{LSPM|}}} |{{nowrap|[[LSPM-North Catalog|LSPM]] {{{LSPM}}}}}}}
| {{#if:{{{LTT|}}} |[[Luyten Two-Tenths catalogue|LTT]] {{{LTT}}}}}
| {{#if:{{{NLTT|}}} |[[NLTT]] {{{NLTT}}}}}
| {{#if:{{{PLX|}}} |[[General Catalogue of Trigonometric Parallaxes|PLX]] {{{PLX}}}}}
| {{#if:{{{PM|}}} |[[Proper motion|PM]] {{{PM}}}}}
| {{#if:{{{PM2|}}} |[[Proper motion|PM]] {{{PM2}}}}}
| {{#if:{{{Ross|}}} |[[Ross catalogue|Ross]] {{{Ross}}}}}
| {{#if:{{{SCR|}}} |{{nowrap|[[Super-COSMOS RECONS|SCR]] {{{SCR}}}}}}}
| {{#if:{{{WD|}}} |{{nowrap|[[White dwarf|WD]] {{{WD}}}}}}}
| {{#if:{{{WD2|}}} |{{nowrap|[[White dwarf|WD]] {{{WD2}}}}}}}
| {{#if:{{{WD3|}}} |{{nowrap|[[White dwarf|WD]] {{{WD3}}}}}}}
| {{#if:{{{Wolf|}}} |[[Max Wolf|Wolf]] {{{Wolf}}}}}
<!-- Exoplanet surveys -->
| {{#if:{{{Kepler|}}} |{{nowrap|[[Kepler space telescope|Kepler]]-{{{Kepler}}}}}}}
| {{#if:{{{KOI|}}} |{{nowrap|[[Kepler object of interest|KOI]]-{{{KOI}}}}}}}
| {{#if:{{{KIC|}}} |{{nowrap|[[Kepler Input Catalog|KIC]] {{{KIC}}}}}}}
| {{#if:{{{EPIC|}}} |{{nowrap|[[Ecliptic Plane Input Catalog|EPIC]] {{{EPIC}}}}}}}
| {{#if:{{{TOI|}}} |{{nowrap|[[Tess object of interest|TOI]]-{{{TOI}}}}}}}
| {{#if:{{{TIC|}}} |{{nowrap|[[TESS Input Catalog|TIC]] {{{TIC}}}}}}}
<!-- Extensive star surveys -->
| {{#if:{{{TYC|}}} |{{nowrap|[[Tycho Catalogue|TYC]] {{{TYC}}}}}}}
| {{#if:{{{GCRV|}}} |{{nowrap|[[GCRV]] {{{GCRV}}}}}}}
| {{#if:{{{GSC|}}} |{{nowrap|[[Guide Star Catalog|GSC]] {{{GSC}}}}}}}
| {{#if:{{{IRAS|}}} |{{nowrap|[[IRAS]] {{{IRAS}}}}}}}
| {{#if:{{{2MASS|}}}|{{nowrap|[[2MASS]] {{{2MASS}}}}}}}
| {{#if:{{{2MASX|}}}|{{nowrap|[[2MASX]] {{{2MASX}}}}}}}
| {{#if:{{{DENIS|}}}|{{nowrap|[[DENIS]] {{{DENIS}}}}}}}
| {{#if:{{{WISE|}}} |{{nowrap|[[Wide-field Infrared Survey Explorer|WISE]] {{{WISE}}}}}}}
| {{#if:{{{WISEA|}}}|{{nowrap|[[Wide-field Infrared Survey Explorer|WISEA]] {{{WISEA}}}}}}}
<!-- Galaxy catalogs -->
| {{#if:{{{NGC|}}} |{{nowrap|[[New General Catalogue|NGC]] {{{NGC}}}}}}}
| {{#if:{{{IC|}}} |{{nowrap|[[Index Catalogue|IC]] {{{IC}}}}}}}
| {{#if:{{{Arp|}}} |{{nowrap|[[Atlas of Peculiar Galaxies|Arp]] {{{Arp}}}}}}}
| {{#if:{{{UGC|}}} |{{nowrap|[[Uppsala General Catalogue|UGC]] {{{UGC}}}}}}}
| {{#if:{{{UGCA|}}} |{{nowrap|[[UGCA]] {{{UGCA}}}}}}}
| {{#if:{{{LEDA|}}} |{{nowrap|[[Lyon-Meudon Extragalactic Database|LEDA]] {{{LEDA}}}}}}}
| {{#if:{{{MCG|}}} |{{nowrap|[[Morphological Catalogue of Galaxies|MCG]] {{{MCG}}}}}}}
| {{#if:{{{MRK|}}} |{{nowrap|[[Markarian galaxies|Mrk]] {{{MRK}}}}}}}
| {{#if:{{{PGC|}}} |{{nowrap|[[Principal Galaxies Catalogue|PGC]] {{{PGC}}}}}}}
| {{#if:{{{CGCG|}}} |{{nowrap|[[Catalogue of Galaxies and of Clusters of Galaxies|CGCG]] {{{CGCG}}}}}}}
| {{#if:{{{VV|}}} |{{nowrap|[[Vorontsov-Vel'yaminov Interacting Galaxies|VV]] {{{VV}}}}}}}
| {{#if:{{{KPG|}}} |KPG {{{KPG}}}}}
| {{#if:{{{SDSS|}}} |{{nowrap|[[Sloan Digital Sky Survey|SDSS]] {{{SDSS}}}}}}}
}}<noinclude>
{{documentation|content=
This template may be used to create a list of other designations within [[Template:Starbox catalog]] or [[Template:Infobox galaxy]].
== Usage ==
A blank template with all the possible parameters is given below. You may delete any unused parameters.
<pre>
{{odlist
| name =
| name2 =
| name3 =
| name4 =
| name5 =
| 2MASS = <!-- Two Micron All-Sky Survey -->
| AC = <!-- Carte du Ciel -->
| AG = <!-- Astronomische Gesellschaft Katalog -->
| ADS = <!-- Aitken Double Star Catalogue -->
| B = <!-- Bayer designation -->
| BD = <!-- Bonner Durchmusterung -->
| BPM = <!-- Bruce Proper Motion survey -->
| CCDM = <!-- Catalogue of Components of Double and Multiple Stars -->
| CD = <!-- Cordoba Durchmusterung -->
| Ci 18 = <!-- Cincinnati Observatory -->
| Ci 20 = <!-- Cincinnati Observatory -->
| CP = <!-- Cape Photographic Durchmusterung -->
| CPD = <!-- Cape Photographic Durchmusterung -->
| DC = <!-- Washington Double Star Catalog discovery code (see WDS) -->
| DENIS = <!-- Deep Near Infrared Survey of the Southern Sky -->
| EGGR = <!-- Olin J. Eggen -->
| EPIC = <!-- Ecliptic Plane Input Catalog -->
| F = <!-- Flamsteed designation -->
| FK5 = <!-- Fifth Fundamental Catalogue -->
| G = <!-- Henry L. Giclas catalogue -->
| G2 = <!-- Henry L. Giclas catalogue -->
| G3 = <!-- Henry L. Giclas catalogue -->
| Gaia DR1 = <!-- Gaia data release 1 -->
| Gaia DR2 = <!-- Gaia data release 2 -->
| GCRV = <!-- General Catalogue of Stellar Radial Velocities -->
| GJ = <!-- Gliese-Jahreiss catalogue -->
| GJ2 = <!-- Gliese-Jahreiss catalogue -->
| Gould = <!-- Uranometria Argentina catalogue -->
| GSC = <!-- Guide Star Catalog -->
| HD = <!-- Henry Draper Catalogue -->
| HIP = <!-- Hipparcos Catalogue -->
| HR = <!-- Harvard Revised catalogue -->
| IRAS = <!-- Infrared Astronomical Satellite -->
| Kepler = <!-- Kepler -->
| KIC = <!-- Kepler Input Catalogue -->
| KOI = <!-- Kepler Object of Interest -->
| L = <!-- Luyten -->
| LAL = <!-- Histoire céleste française -->
| LAWD = <!-- Luyten Atlas of White Dwarfs -->
| LDS = <!-- Luyten Double Stars catalogue -->
| LP = <!-- Luyten-Palomar proper motion catalogue -->
| LPM = <!-- Luyten Proper-Motion Catalogue -->
| LFT = <!-- Luyten Five-Tenths catalogue -->
| LHS = <!-- Luyten Half-Second Catalogue -->
| LSPM = <!-- LSPM-North Catalog -->
| LTT = <!-- Luyten Two-Tenths catalogue -->
| NLTT = <!-- New Luyten Two-Tenths Catalogue -->
| NSV = <!-- New Catalogue of Suspected Variable Stars -->
| PLX = <!-- General Catalogue of Trigonometric Parallaxes -->
| PM = <!-- Proper motion -->
| PM2 = <!-- Proper motion -->
| PPM = <!-- Position and proper motion catalogue -->
| Ross = <!-- Ross catalogue -->
| SAO = <!-- Smithsonian Astrophysical Observatory Star Catalogue -->
| SCR = <!-- Super-COSMOS RECONS -->
| TOI = <!-- Tess Object of Interest -->
| TYC = <!-- Tycho Catalogue -->
| V = <!-- Variable star designation -->
| WD = <!-- White dwarf -->
| WD2 = <!-- White dwarf -->
| WD3 = <!-- White dwarf -->
| WDS = <!-- Washington Double Star Catalog -->
| WISE = <!-- Wide-field Infrared Survey Explorer -->
| WISEA = <!-- Wide-field Infrared Survey Explorer - All-Sky -->
| Wolf = <!-- Max Wolf -->
}}</pre>
For galaxies, use this one:
<pre>
{{odlist
| name =
| name2 =
| name3 =
| name4 =
| name5 =
| Arp = <!-- Atlas of Peculiar Galaxies -->
| IC = <!-- Index Catalogue -->
| LEDA = <!-- Lyon-Meudon Extragalactic Database -->
| MCG = <!-- Morphological Catalogue of Galaxies -->
| MRK = <!-- Markarian galaxies -->
| NGC = <!-- New General Catalogue -->
| PGC = <!-- Principal Galaxies Catalogue -->
| UGC = <!-- Uppsala General Catalogue -->
| UGCA = <!-- Uppsala General Catalogue Addendum -->
| 2MASS = <!-- Two Micron All-Sky Survey -->
| 2MASX = <!-- Two Micron All-Sky Survey Extended Source Catalog -->
| CGCG = <!-- Catalogue of Galaxies and of Clusters of Galaxies -->
| VV = <!-- Vorontsov-Vel'yaminov Interacting Galaxies -->
| KPG = <!-- Karachentsev Catalogue of Isolated Pairs of Galaxies -->
| SDSS = <!-- Sloan Digital Sky Survey -->
}}</pre>
[[Category:Astronomy templates]]
}}</noinclude>
a5bf09051821f2310a8126a5829dc0cbd7e51dd9
Module:Portal/images/a
828
117
249
2022-07-27T15:07:14Z
Canopus >Buaidh
0
["algeria"] = "Flag of Algeria.svg|border|link=|alt=flag",
Scribunto
text/plain
--[==[ This is the "A" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "A". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be
-- omitted.
]==]
return {
["airports"] = "Round Landmark Icon Airport.svg|link=|alt=",
["aarhus"] = "Coat of arms of Aarhus.svg|alt=icon",
["abkhazia"] = "Flag of Abkhazia.svg|border|link=|alt=flag",
["aboriginal peoples in canada"] = "Aboriginal War Veterans monument (close).JPG|alt=icon",
["abu dhabi"] = "Flag of Abu Dhabi.svg|border|link=|alt=flag",
["acipenseriformes"] = "Acipenser oxyrhynchus (edit).png|link=|alt=icon",
["actors and filmmakers"] = "Charlie Chaplin 1912.jpg|link=|alt=photo",
["ac/dc"] = "Acdc logo band.svg|link=|alt=",
["academy award"] = "Video-x-generic.svg|link=|alt=",
["acadia"] = "Flag of Acadia.svg|border|link=|alt=flag",
["acc"] = "ACC Map crop 2014.png|alt=icon",
["adelaide"] = "Escudo de Adelaida.png|alt=icon",
["adobe flash"] = "Adobe Flash Player v11 icon.png|link=|alt=logo",
["advent"] = "Candle4.png|alt=Advent candle",
["aerosmith"] = "Joe Perry 1.jpg|alt=icon",
["aerospace biography"] = "Armstrong-Spencom01.jpg|link=|alt=photo",
["aesthetics"] = "Morning Glory Flower square.jpg|alt=icon",
["afghanistan"] = "Flag of the Taliban.svg|border|link=|alt=flag",
["africa"] = "Africa (orthographic projection).svg|link=|alt=map",
["african american"] = "Kleed- Stichting Nationaal Museum van Wereldculturen - RV-5899-18 (cropped).jpg|alt=icon",
["african cuisine"] = "Africa icon.png|link=|alt=",
["african diaspora"] = "Moromi.png|link=|alt=map",
["african union"] = "Flag of the African Union.svg|border|link=|alt=flag",
["afro-eurasia"] = "Afro-Eurasia (orthographic projection).svg|link=|alt=map",
["agriculture"] = "Veranotrigo.jpg|alt=icon",
["agriculture and agronomy"] = "Veranotrigo.jpg|alt=icon",
["agropedia"] = "Farmer plowing in Fahrenwalde, Mecklenburg-Vorpommern, Germany.jpg|alt=icon",
["aguascalientes"] = "Flag of Aguascalientes.svg|border|link=|alt=flag",
["ahmadiyya"] = "White Minaret Symbol.png|alt=icon",
["ahmedabad"] = "Mosque of Sidi Sayed Jaali.JPG|alt=icon",
["ai"] = "ArtificialFictionBrain.png|alt=icon",
["ajman"] = "Flag of Ajman.svg|link=|alt=flag",
["akb48"] = "AKB48 logo2.svg|link=|alt=",
["alabama"] = "Flag of Alabama.svg|border|link=|alt=flag",
["alaska"] = "Flag of Alaska.svg|border|link=|alt=flag",
["albania"] = "Flag of Albania.svg|border|link=|alt=flag",
["albemarle county"] = "Monticello 2010-10-29.jpg|link=|alt=photo",
["alberta"] = "Flag of Alberta.svg|border|link=|alt=flag",
["alcoholic drinks"] = "Mitch (cocktail).jpg|link=|alt=",
["a-league"] = "Soccer ball.svg|alt=icon",
["algae"] = "Algae Graphic.svg|link=|alt=icon",
["algebra"] = "Arithmetic symbols.svg|link=|alt=",
["algeria"] = "Flag of Algeria.svg|border|link=|alt=flag",
["almaty"] = "Flag of Almaty.svg|alt=flag",
["alps"] = "Palü en Diavolezza.jpg|alt=icon",
["alternative medicine"] = "Rod of Asclepius2.svg|alt=icon",
["alternative rock"] = "Guitar 1.svg|link=|alt=icon",
["american animation"] = "Animation disc US.svg|link=|alt=icon",
["american cinema"] = "Cinema of the United States.svg|link=|alt=icon",
["american civil war"] = "Acw bs 7a.png|border|link=|alt=",
["american cuisine"] = "Americanbandstand-1.jpg|link=|alt=",
["american football"] = "American football.svg|link=|alt=icon",
["american football league"] = "AFL Trophy alt.png|link=|alt=trophy",
["american music"] = "Musical Notes USA.svg|link=|alt=icon",
["american old west"] = "Frederic Remington Dismounted Moving Led Horses.jpg|link=|alt=painting",
["american open wheel racing"] = "JuanMontoya2015Indy500.JPG|link=|alt=photo",
["american revolutionary war"] = "Washington Crossing the Delaware by Emanuel Leutze, MMA-NYC, 1851.jpg|border|link=|alt=",
["american samoa"] = "Flag of American Samoa.svg|border|link=|alt=flag",
["american television"] = "USA flag on television.svg|link=|alt=icon",
["americas"] = "Americas (orthographic projection).svg|link=|alt=map",
["amiga"] = "Boingball.png|link=|alt=",
["amphibians"] = "Frog (2546) - The Noun Project.svg|link=|alt=",
["amphibians and reptiles"] = "Lizardicon.svg|link=|alt=",
["amusement parks"] = "Roller Coaster Icon.svg|link=|alt=",
["anabaptism"] = "Dirk.willems.rescue.ncs.jpg|link=|alt=",
["analysis"] = "Nuvola apps kmplot.svg|alt=icon",
["analytical chemistry"] = "Nuvola apps edu science.svg|alt=icon",
["anarchism"] = "BlackFlagSymbol.svg|border|link=|alt=flag",
["andes"] = "Ausangate-hillside-MT.jpg|alt=",
["andorra la vella"] = "Flag of Andorra la Vella.svg|alt=flag",
["apples"] = "Apple icon 1.png|link=|alt=",
["argentine cuisine"] = "Argentine cuisine title.jpg|link=|alt=",
["anatomy"] = "Anatomy posture and body mechanics 08.web.jpg|alt=icon",
["ancient egypt"] = "Pyramidi aavikolla.png|link=|alt=",
["ancient germanic culture"] = "Mjollnir icon.png|link=|alt=",
["ancient greece"] = "Parthenon from west.jpg|link=|alt=",
["ancient japan"] = "Shiki no Fuji, Ōmuro fukin by Takahashi Shōtei.jpg|link=|alt=",
["ancient near east"] = "Babylonlion.JPG|link=|alt=",
["ancient rome"] = "SPQRomani.svg|link=|alt=",
["andaman and nicobar islands"] = "India Andaman and Nicobar Islands locator map.svg|border|link=|alt=map",
["andhra pradesh"] = "Archbridgegodavari.JPG|alt=icon",
["andorra"] = "Flag of Andorra.svg|border|link=|alt=flag",
["android (operating system)"] = "Android robot.svg|link=|alt=icon",
["anglicanism"] = "Canterbury cathedral.jpg|link=|alt=",
["anglo-saxon england"] = "Peterborough Chronicle cropped.jpg|link=|alt=",
["angola"] = "Flag of Angola.svg|border|link=|alt=flag",
["anguilla"] = "Flag of Anguilla.svg|border|link=|alt=flag",
["animal rights"] = "Paw (Animal Rights symbol).svg|alt=icon",
["animals"] = "Caribou from Wagon Trails.jpg|alt=icon",
["animation"] = "Animation disc.svg|alt=icon",
["animation/canadian animation work group"] = "Animation disc Maple Leaf.svg|alt=icon",
["anime and manga"] = "Wikipe-tan face.svg|alt=icon",
["antarctica"] = "Antarctica (orthographic projection).svg|link=|alt=map",
["anthropology"] = "Moai Easter Island InvMH-35-61-1.jpg|link=|alt=",
["antigua and barbuda"] = "Flag of Antigua and Barbuda.svg|border|link=|alt=flag",
["antwerp"] = "Coat of arms of Antwerp (City).svg|alt=icon",
["appalachia"] = "Appalachian region of United States.png|border|link=|alt=map",
["apple inc."] = "Apple logo black.svg|link=|alt=",
["applied science"] = "Metallurgy stub icon.svg|link=|alt=icon",
["aquarium fish"] = "Pterois antennata-3.jpg|link=|alt=",
["arab world"] = "Flag of the Arab League.svg|border|link=|alt=flag",
["arabic language"] = "Arabic-dad-letter.svg|link=Arabic language|alt=icon",
["archaeology"] = "Stonehenge Closeup.jpg|link=|alt=",
["architecture"] = "P parthenon.svg|alt=icon",
["arctic"] = "Arctic (orthographic projection).svg|link=|alt=map",
["argentina"] = "Flag of Argentina.svg|border|link=|alt=flag",
["arithmetic"] = "Arithmetic symbols.svg|link=|alt=",
["arizona"] = "Flag of Arizona.svg|border|link=|alt=flag",
["arkansas"] = "Flag of Arkansas.svg|border|link=|alt=flag",
["armenia"] = "Flag of Armenia.svg|border|link=|alt=flag",
["arminianism"] = "Arminius 5 flopped and cropped.png|link=|alt=",
["arunachal pradesh"] = "India Arunachal Pradesh locator map.svg|link=|alt=map",
["art"] = "Ballerina-icon.jpg|alt=icon",
["arthropods"] = "Cercophonius squama.jpg|alt=icon",
["artificial intelligence"] = "Animation2.gif|alt=icon",
["arts"] = "Nuvola apps package graphics.png|alt=icon",
["artsakh"] = "Flag of Artsakh.svg|border|link=|alt=flag",
["arts and entertainment"] = "Meryl in 1990.jpg|link=|alt=photo",
["aruba"] = "Flag of Aruba.svg|border|link=|alt=flag",
["asia"] = "Asia (orthographic projection).svg|alt=icon",
["asian games"] = "Asian Games logo01.png|link=|alt=",
["aspect ratio 1.000"] = "Flag of Switzerland.svg|link=|alt=image",
["aspect ratio 1.333"] = "Flag of Gabon.svg|link=|alt=image",
["aspect ratio 1.400"] = "Flag of Kosovo.svg|link=|alt=image",
["aspect ratio 1.500"] = "Flag of the European Union.svg|link=|alt=image",
["aspect ratio 1.667"] = "Flag of Bangladesh.svg|link=|alt=image",
["aspect ratio 2.000"] = "Flag of the United Kingdom.svg|link=|alt=image",
["assam"] = "Seal of Assam.png|link=|alt=",
["association football"] = "Soccer ball.svg|alt=icon",
["assyrians"] = "Flag of Assyria.svg|border|link=|alt=flag",
["astrobiology"] = "PIA01130 Interior of Europa.jpg|link=|alt=",
["astrology"] = "Astrologia-tynkä.jpg|link=|alt=",
["astronomy"] = "Crab Nebula.jpg|link=|alt=",
["atheism"] = "Atheism template.svg|alt=icon",
["athletics"] = "Athletics pictogram.svg|link=|alt=",
["atlanta"] = "Atlflag.svg|link=|alt=flag",
["atlantic ocean"] = "Atlantic Ocean - en IHO.png|link=|alt=map",
["atlas"] = "World map green.png|alt=icon",
["atmospheric science"] = "Cumulus clouds in fair weather.jpeg|link=|alt=icon",
["atoms"] = "Stylised atom with three Bohr model orbits and stylised nucleus.svg|link=|alt=",
["austin"] = "Sixth Street Austin.jpg|alt=icon",
["australasia"] = "Oceania (orthographic projection).svg|link=|alt=map",
["australia"] = "Flag of Australia.svg|border|link=|alt=flag",
["australian army"] = "Australian Army Emblem Transparent.png|border|link=|alt=icon",
["australian capital territory"] = "Flag of the Australian Capital Territory.svg|border|link=|alt=flag",
["australian continent"] = "Australia (orthographic projection).svg|link=|alt=map",
["australian roads"] = "Australia road sign W5-29.svg|alt=icon",
["australian rules football"] = "Sherrin-transparent.png|link=|alt=",
["austria"] = "Flag of Austria.svg|border|link=|alt=flag",
["austria-hungary"] = "Wappen Österreich-Ungarn 1916 (Klein).png|link=|alt=",
["automobiles"] = "Sportcar sergio luiz ara 01.svg|link=|alt=",
["automotive industry in japan"] = "Car with Driver-Silhouette.svg|link=|alt=",
["aviation"] = "Aviacionavion.png|link=|alt=",
["avril lavigne"] = "LetGo.jpg|alt=icon",
["ayyavazhi"] = "Ayyavazh logo transperent.png|alt=icon",
["azad kashmir"] = "Flag of Azad Kashmir.svg|border|link=|alt=flag",
["azerbaijan"] = "Flag of Azerbaijan.svg|border|link=|alt=flag",
["azores"] = "Flag of the Azores.svg|border|link=|alt=flag"
}
2ed9709a584c9486757ce4112bbf87096eb6b3be
Module:Portal/images/aliases
828
122
259
2022-07-28T02:55:56Z
Canopus >Buaidh
0
["south georgia and the south sandwich islands"] = {"south georgia", "south sandwich islands", "gs", "sgs"},
Scribunto
text/plain
--[==[ This is the "aliases" list of portal image names. It contains a list of portal image aliases for use with [[Module:Portal]].
-- The aliases can be used to point to an existing portal image entry. For portals who do not yet have a portal image entry, please
-- use the appropriate page from the following list instead:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- When adding entries, please use alphabetical order. The format of the alias table entries is as follows:
-- ["portal name"] = {"alias 1", "alias 2", "alias 3"},
-- Both the portal name and the alias names should be in lower case, and the "Portal:" namespace prefix
-- should be omitted. For example, if you wanted "UK" to be an alias for "Portal:United Kingdom", then the
-- alias name would be "uk" and the portal name would be "united kingdom".
]==]
return {
["1990s"] = {"1990's"},
["2000s"] = {"2000's"},
["ac/dc"] = {"ac dc"},
["academy award"] = {"academy awards"},
["african american"] = {"african-american", "african-americans", "african americans"},
["african union"] = {"au"},
["agriculture and agronomy"] = {"agriculture"},
["american civil war"] = {"acw"},
["american revolutionary war"] = {"american revolution"},
["amphibians"] = {"amphibian"},
["aviation"] = {"airplanes"},
["åland"] = {"åland islands", "aland islands", "aland", "ax", "ala"},
["albania"] = {"albanian", "al", "alb"},
["american football"] = {"college football", "arena football league"},
["android (operating system)"] = {"android", "android os"},
["apple inc."] = {"apple", "apple inc"},
["arabic language"] = {"arabic"},
["archaeology"] = {"archeology"},
["asian americans"] = {"asian american"},
["association football"] = {"soccer"},
["assyrians"] = {"assyria"},
["atlas"] = {"cartography"},
["atmospheric science"] = {"atmosphere","atmospheric sciences"},
["australia"] = {"australian", "aus"},
["australian capital territory"] = {"canberra"},
["banks"] = {"bank", "banking"},
["baseball"] = {"college baseball", "little league"},
["basketball"] = {"national basketball league of canada", "wnba"},
["biography"] = {"people", "biographies"},
["birds"] = {"bird"},
["björk"] = {"bjork"},
["books"] = {"book"},
["brunei"] = {"brunei darussalam", "bn", "brn"},
["business and economics"] = {"advertising", "business", "economics", "economy", "marketing"},
["buses"] = {"bus"},
["california roads"] = {"roads in california"},
["california state polytechnic university, pomona"] = {"cal poly pomona"},
["canada"] = {"canadian", "ca", "can"},
["canadian armed forces"] = {"canadian forces", "military history of canada"},
["canary islands"] = {"spanish africa"},
["caribbean"] = {"caribbean sea", "west indies"},
["cars"] = {"car", "automobile"},
["cartoon"] = {"cartoons"},
["catalan-speaking countries"] = {"catalan", "catalonia"},
["cats"] = {"cat"},
["celtic studies"] = {"celts"},
["children's literature"] = {"children's and young adult literature", "children and young adult literature"},
["china"] = {"chinese", "cn", "chn"},
["christiantiy"] = {"christ", "christian"},
["christianity in india"] = {"indian christianity"},
["classical civilisation"] = {"classical civilization", "classics"},
["cleveland"] = {"cleveland, ohio"},
["coconuts"] = {"coconut"},
["color"] = {"colour"},
["comedy"] = {"humour", "humor"},
["commonwealth realms"] = {"commonwealth"},
["compact disc"] = {"cd", "compact disk"},
["companies"] = {"company"},
["computer-generated imagery"] = {"computer generated imagery"},
["computer programming"] = {"programming"},
["county kilkenny"] = {"kilkenny"},
["criminal justice"] = {"crime"},
["current events"] = {"events"},
["czech republic"] = {"czechia", "czech"},
["dallas – fort worth metroplex"] = {"dallas", "dallas-fort worth", "dallas - fort worth metroplex"},
["democratic republic of the congo"] = {"zaire", "zaïre", "cod", "drc", "the democratic republic of the congo"},
["denmark"] = {"kingdom of denmark", "danish", "dk", "dnk"},
["disasters"] = {"disaster"},
["dravidian languages"] = {"dravidian", "dravidia", "dravidian peoples", "dravidian civilization"},
["dominican republic"] = {"the dominican republic"},
["durham, north carolina"] = {"durham nc"},
["dungeons & dragons"] = {"d&d"},
["east timor"] = {"timor leste", "tl"},
["electromagnetism"] = {"em"},
["english football"] = {"football in england"},
["english language"] = {"english"},
["erotica and pornography"] = {"porn", "pornography"},
["european military history"] = {"military history of europe"},
["european union"] = {"eu"},
["evolutionary biology"] = {"evolution"},
["extinct and endangered species"] = {"extinction", "endangered species"},
["falkland islands"] = {"falkland", "malvinas", "fk", "flk"},
["faroe islands"] = {"the faroe islands"},
["federated states of micronesia"] = {"fm", "fsm"},
["film"] = {"films"},
["football"] = {"association football", "soccer", "soccer ball"},
["formula one"] = {"f1", "formula 1"},
["free and open-source software"] = {"free and open source software", "free software", "foss", "open source software", "open-source software", "oss"},
["freedom of speech"] = {"censorship", "free speech"},
["french and francophone literature"] = {"french literature"},
["french politics"] = {"politics of france"},
["gardening"] = {"gardening and horticulture"},
["gemology and jewelry"] = {"gemmology and jewellery", "gemmology and jewelry", "gemology and jewellery"},
["georgia (country)"] = {"georgia", "republic of georgia", "ge", "geo"},
["georgia (u.s. state)"] = {"georgia (state)"},
["globalization"] = {"globalisation"},
["gullah"] = {"gullah people"},
["hawaii"] = {"hawai'i", "hawaiʻi", "us-hi"},
["hazardous materials"] = {"dangerous goods"},
["health and fitness"] = {"health"},
["himalayas"] = {"himalaya region"},
["hindustani"] = {"hindustani language", "hindustani and allied languages"},
["hip hop"] = {"hip-hop"},
["hispanic and latino americans"] = {"hispanic and latino american", "latino and hispanic americans", "latino and hispanic american"},
["horror fiction"] = {"horror"},
["horticulture and gardening"] = {"horticulture"},
["hunger relief"] = {"hunger"},
["india"] = {"indian", "in", "ind", "republic of india"},
["indian women"] = {"women of india", "indian women and gender issues"},
["indiana"] = {"hoosier", "us-in"},
["indigenous peoples of north america"] = {"indigenous people of north america"},
["information technology"] = {"computing", "computer science", "it"},
["insects"] = {"insect"},
["ireland"] = {"irish"},
["islam"] = {"muslim history"},
["islamic state of iraq and the levant"] = {"daesh", "isil", "isis"},
["islands"] = {"island"},
["italy"] = {"italian", "ita"},
["jacksonville, florida"] = {"jacksonville"},
["kazi nazrul islam"] = {"nazrul"},
["latter day saint movement"] = {"lds"},
["lemony snicket"] = {"a series of unfortunate events"},
["lgbt"] = {"lgbtq", "lgbtqa"},
["library and information science"] = {"information science"},
["madonna (entertainer)"] = {"madonna"},
["mediterranean"] = {"mediterranean sea"},
["metro detroit"] = {"detroit"},
["mexico"] = {"méxico", "mx", "mex"},
["middle tennessee state university"] = {"mtsu"},
["michigan highways"] = {"highways in michigan"},
["molecular and cell biology"] = {"molecular and cellular biology"},
["moldova"] = {"republic of moldova"},
["mongolia"] = {"mongols"},
["mountains"] = {"mountain"},
["music of australia"] = {"australian music"},
["myanmar"] = {"burma", "burmese", "mm", "mmr"},
["national register of historic places"] = {"nrhp"},
["nazism"] = {"nazi germany"},
["netherlands"] = {"kingdom of the netherlands", "nl", 'nld', 'caribbean netherlands', 'the netherlands', 'dutch empire', 'the dutch empire'},
["new york"] = {"new york state", "new york (state)", "us-ny"},
["new york city"] = {"nyc"},
["new zealand"] = {"nz", "nzl"},
["north korea"] = {"dprk", "democratic people's republic of korea"},
["north macedonia"] = {"republic of north macedonia", "mk", "mkd"},
["north rhine-westphalia"] = {"nrw"},
["oceans"] = {"ocean", "world ocean"},
["odisha"] = {"orissa"},
["opera"] = {"operas"},
["organized labour"] = {"organised labour", "organized labor"},
["pakistan"] = {"pakistani", "pk", "pak"},
["paleontology"] = {"palaeontology"},
["palestine"] = {"the state of palestine","state of palestine"},
["paralympic games"] = {"paralympics"},
["pan-africanism"] = {"pan-african"},
["people's republic of china"] = {"prc"},
["pharmacy and pharmacology"] = {"pharmacy"},
["pitcairn islands"] = {"pitcairn, henderson, ducie and oeno islands"},
["politics"] = {"government"},
["prince edward island"] = {"pei", "ca-pe"},
["protected areas of india"] = {"biodiversity, protected areas & environment of india", "biodiversity of india", "environment of india"},
["puducherry"] = {"pondicherry", "in-py"},
["punjab, india"] = {"punjab (india)", "in-pb"},
["punjab, pakistan"] = {"punjab (pakistan)", "western punjab", "pk-pb"},
["python programming"] = {"python"},
["quebec"] = {"québec", "ca-qc"},
["religion"] = {"religions"},
["republic of ireland"] = {"éire", "ie", "irl", "irish republicanism"},
["republic of north macedonia"] = {"north macedonia", "mk", "mkd", "the republic of macedonia", "republic of macedonia"},
["republic of the congo"] = {"the republic of the congo", "republic of congo", "french congo"},
["roads of canada"] = {"canada roads"},
["romani people"] = {"roma", "romani"},
["saint barthelemy"] = {"saint-barthélemy", "saint barthélemy"},
["saint helena, ascension and tristan da cunha"] = {"saint helena"},
["salad dressing"] = {"salad dressings"},
["sandwich"] = {"sandwiches"},
["schools"] = {"school"},
["serer people"] = {"serer"},
["september 11 attacks"] = {"september 11, 2001"},
["sexuality"] = {"sex"},
["soap operas and telenovelas"] = {"soap operas", "telenovelas"},
["south africa"] = {"za", "zaf"},
["south georgia and the south sandwich islands"] = {"south georgia", "south sandwich islands", "gs", "sgs"},
["soviet union"] = {"ussr"},
["space"] = {"outer space"},
["spices"] = {"herbs and spices"},
["sports in canada"] = {"canadian sports", "canadian sport", "sports of canada", "sport in canada"},
["sports"] = {"sport"},
["st. john's, newfoundland and labrador"] = {"st. john's"},
["state of georgia"] = {"georgia (u.s. state)", "georgia usa", "us-ga"},
["state of mexico"] = {"mexico (state)", "mx-mex"},
["state university of new york"] = {"suny"},
["taiwan"] = {"republic of china", "roc", "tw", "twn"},
["tamil people"] = {"tamil"},
["tanks"] = {"tank"},
["telecommunication"] = {"telecommunications", "telecoms", "telecomms", "telecomm", "telecom"},
["texas a&m university"] = {"texas a&m"},
["texas tech university"] = {"texas tech"},
["theatre"] = {"theater"},
["the bahamas"] = {"bahamas", "bs", "bhs"},
["the gambia"] = {"gambia", "gm", "gmb"},
["the legend of zelda"] = {"legend of zelda"},
["tiruchirappalli"] = {"trichy", "tiruchi"},
["transportation"] = {"transport"},
["trauma and orthopaedics"] = {"trauma & orthopaedics"},
["tropical cyclones"] = {"tropical cyclone"},
["united arab emirates"] = {"emirates", "ae", "uae", "emirati"},
["united kingdom"] = {"the united kingdom", "uk", "gb", "gbr", "british", "british overseas territories"},
["united nations"] = {"un"},
["united states"] = {"us", "usa", "u.s.", "united states armed forces", "american", "territories of the united states"},
["united states arms"] = {"united states armed forces", "united states military", "united states military history", "u.s. armed forces", "u.s. military"},
["united states congress"] = {"u.s. congress"},
["united states counties"] = {"u.s. counties"},
["united states presidents"] = {"u.s. presidents"},
["united states roads"] = {"u.s. roads"},
["united states state legislatures"] = {"u.s. state legislatures", "us state legislatures"},
["united states streets"] = {"u.s. streets"},
["united states supreme court"] = {"u.s. supreme court cases"},
["united states territories"] = {"territories of the united states"},
["university of missouri"] = {"mizzou"},
["university of notre dame"] = {"notre dame"},
["university of pittsburgh"] = {"pitt"},
["video games"] = {"vg", "video game"},
["war"] = {"military"},
["washington (state)"] = {"washington", "us-wa"},
["washington, d.c."] = {"district of columbia", "dc", "washington dc", "us-dc"},
["western asia"] = {"west asia"},
["western sahara"] = {"sahrawi arab democratic republic", "eh", "esh"},
["world war i"] = {"first world war"},
["world war ii"] = {"second world war"},
["zoos"] = {"zoo"}
}
06ad5a8008671463b8305eb44bb61afb68f4f1df
Module:Authority control
828
91
197
2022-07-29T20:40:29Z
Canopus >MSGJ
0
update syntax for NLK
Scribunto
text/plain
require('Module:No globals')
local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
--[[==========================================================================]]
--[[ Category functions ]]
--[[==========================================================================]]
local function addCat( cat )
if cat and cat ~= '' then return '[[Category:'..cat..']]'..p.redCatLink(cat) end
return ''
end
function p.getCatForId( id )
local cat = ''
if namespace == 0 then
cat = 'Articles with '..id..' identifiers'
end
return addCat(cat)
end
function p.redCatLink( cat ) --cat == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')
if cat and cat ~= '' and testcases == false and mw.title.new(cat, 14).exists == false then
return '[[Category:Pages with red-linked authority control categories]]'
end
return ''
end
function p.createRow( id, rawValues, link, links, withUid, specialCat, prefix)
local faultyCat = 'Articles with faulty '..(specialCat or id)..' identifiers'
if links then -- all links[] use withUid = false; no check needed
local row = ''
if prefix then
row = row..'*'..prefix
end
for i, l in ipairs( links ) do
if i == 1 and not prefix then row = row..'*'
else row = row..'\n**' end
if l then
row = row..'<span class="uid">'..l..'</span>'
else
row = row..'<span class="error">The '..id..' id '..rawValues[i]..' is not valid.</span>'..addCat(faultyCat)
end
end
return row..'\n'
elseif link then -- All IDs that have a prefix support multiple identifiers, so prefix is not needed
if withUid then
return '*<span class="nowrap"><span class="uid">'..link..'</span></span>\n'
end
return '*<span class="nowrap">'..link..'</span>\n'
end
return '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>'..addCat(faultyCat)..'\n'
end
--[[==========================================================================]]
--[[ Property formatting functions ]]
--[[==========================================================================]]
-- If a link has a suitable entry in the global inter-wiki prefix table at [[:m:Interwiki_map]],
-- please consider routing through this prefix rather than as external link URL.
-- This will ease future maintenance as necessary updates to the link can be centrally carried out there rather than by updating this module.
-- The "external link" icon would disappear for such entries.
function p.aagLink( id, label)
--P3372's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..(label or 'Auckland')..']'..p.getCatForId( 'AAG' )
end
function p.acmLink( id, label )
--P864's format regex: \d{11} (e.g. 12345678901)
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://dl.acm.org/profile/'..id..' '..(label or 'Association for Computing Machinery')..']'..p.getCatForId( 'ACM-DL' )
end
function p.adbLink( id, label )
--P1907's format regex: [a-z][-a-z]+-([1-3]\d|[1-9])\d{0,3} (e.g. barton-sir-edmund-toby-71)
if not id:match( '^[a-z][-a-z]+-[1-3]%d%d?%d?%d?$' ) and
not id:match( '^[a-z][-a-z]+-[1-9]%d?%d?%d?$' ) then
return false
end
return '[http://adb.anu.edu.au/biography/'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'ADB' )
end
function p.admiraltyLink(id,label)
--P3562's format regex: [A-Q]\d{4}(\.\d+)? (e.g. D1204.1)
if not id:match('^[A-Q]%d%d%d%d$') and
not id:match('^[A-Q]%d%d%d%d%.%d+$') then
return false
end
return id..p.getCatForId( 'admiralty' )
end
function p.agsaLink( id, label )
--P6804's format regex: [1-9]\d* (e.g. 3625)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..(label or 'South Australia')..']'..p.getCatForId( 'AGSA' )
end
function p.ARLHSLink(id,label)
--P2980's format regex: [A-Z]{3}\d{3,4}[A-Z]?| e.g. LAT023
if not id:match('^[A-Z][A-Z][A-Z]%d%d%d%d?[A-Z]?$') then
return false
end
return '[http://wlol.arlhs.com/lighthouse/'..id..'.html '..(label or 'ARLHS')..']'..p.getCatForId( 'ARLHS' )
end
function p.autoresuyLink( id, label )
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
if not id:match( '^[1-9]%d?%d?%d?%d?$' ) then
return false
end
return '[https://autores.uy/autor/'..id..' '..(label or 'Uruguay')..']'..p.getCatForId( 'autores.uy' )
end
function p.awrLink( id, label )
--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
return false
end
return '[http://www.womenaustralia.info/biogs/'..id..'.htm '..(label or 'Australian Women\'s Register')..']'..p.getCatForId( 'AWR' )
end
function p.bibsysLink( id, label )
--P1015's format regex: [1-9]\d* or [1-9](\d{0,8}|\d{12}) (e.g. 1234567890123)
--TODO: follow up @ [[d:Property talk:P1015#Discrepancy between the 2 regex constraints]] or escalate/investigate
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..(label or 'Norway')..']'..p.getCatForId( 'BIBSYS' )
end
function p.bildLink( id, label )
--P2092's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.bildindex.de/document/obj'..id..' '..(label or 'Bildindex (Germany)')..']'..p.getCatForId( 'Bildindex' )
end
function p.bncLink( id, label )
--P1890's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..(label or 'Chile')..']'..p.getCatForId( 'BNC' )
end
function p.bneLink( id, label )
--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
not id:match( '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..(label or 'Spain')..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019
end
function p.bnfLink( id, label )
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
return false
end
--Add cb prefix if it has been removed
if not id:match( '^cb.+$' ) then
id = 'cb'..id
end
return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..(label or 'France')..'] [https://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )
end
function p.bnmmLink( id, label )
--P3788's format regex: \d{9} (e.g. 000024044)
if id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return '[https://catalogo.bn.gov.ar/F/?func=direct&local_base=BNA10&doc_number='..id..' '..(label or 'Argentina')..']'..p.getCatForId( 'BNMM' )
else
return false
end
end
function p.botanistLink( id, label )
--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(Ma?c)?[\p{Lu}bht]?C?['\p{Ll}]*)*\.? ?f?\.? (e.g. L.)
--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing
return false
end
id = id:gsub(' +', '%%20')
return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id..' '..(label or 'International Plant Names Index')..']'..p.getCatForId( 'Botanist' )
end
function p.bpnLink( id, label )
--P651's format regex: \d{6,8} (e.g. 00123456)
if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
not id:match( '^0?0?%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end
function p.canticLink( id, label )
--P1273's format regex: a\d{7}[0-9x] (e.g. a10640745)
if not id:match( '^a%d%d%d%d%d%d%d[%dx]$' ) then
return false
end
return '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..(label or 'Catalonia')..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end
function p.canticnLink( id, label )
--P9984's format regex: 981(0|1)\d{9}06706 (e.g. 981058515460906706)
if not id:match( '^981[0-1]%d%d%d%d%d%d%d%d%d06706$' ) then
return false
end
return '[https://cantic.bnc.cat/registre/'..id..' '..(label or 'Catalonia')..']'..p.getCatForId( 'CANTICN' )
end
function p.ccgLink( id, label )
--P3920's format regex: ([NAIP])?[1-9]\d*(\.\d+)? (e.g. A1761)
if not id:match( '^[NAIP]?[1-9]%d*$' ) and
not id:match( '^[NAIP]?[1-9]%d*%.%d+$' ) then
return false
end
return id..p.getCatForId( 'CCG' )
end
function p.ciniiLink( id, label )
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..(label or 'CiNii (Japan)')..']'..p.getCatForId( 'CINII' )
end
function p.cwgcLink( id, label )
--P1908's format regex: [1-9]\d* (e.g. 75228351)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://www.cwgc.org/find-war-dead/casualty/'..id..'/ '..(label or 'Commonwealth War Graves Commission')..']'..p.getCatForId( 'CWGC' )
end
function p.emuLink( id, label )
--P4613's format regex: \d{1,6} (e.g. 15409 (or 015409))
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://esu.com.ua/search_articles.php?id='..id..' '..(label or 'Ukraine')..']'..p.getCatForId( 'EMU' )
end
function p.daaoLink( id, label )
--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
if not id:match( '^[a-z%-]+%d*$' ) then
return false
end
return '[https://www.daao.org.au/bio/'..id..' '..(label or 'Australian Artists')..']'..p.getCatForId( 'DAAO' )
end
function p.dblpLink( id, label )
--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
if not id:match( '^%d%d%d?/%d+$' ) and
not id:match( '^%d%d%d?/%d+%-%d+$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
return false
end
return '[https://dblp.org/pid/'..id..' '..(label or 'DBLP (computer science)')..']'..p.getCatForId( 'DBLP' )
end
function p.dibLink( id, label )
--P6829's format regex: 0[01]\d{4}(\.[A-D])? (e.g. 001953)
if not id:match( '^0[01]%d%d%d%d%.?[A-D]?$' ) then
return false
end
return '[https://dib.cambridge.org/viewReadPage.do?articleId='..id..' '..(label or 'Ireland')..']'..p.getCatForId( 'DIB' )
end
function p.dsiLink( id, label )
--P2349's format regex: [1-9]\d* (e.g. 1538)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..(label or 'Scientific illustrators')..']'..p.getCatForId( 'DSI' )
end
function p.dtbioLink( id, label )
--P7902's format regex: 1[0-9]{7,8}[0-9X] (e.g. 118554700)
if not id:match( '^1[0-9]%d%d%d%d%d%d%d?[0-9X]$' ) then
return false
end
return '[https://www.deutsche-biographie.de/pnd'..id..'.html?language=en '..(label or 'Germany')..']'..p.getCatForId( 'DTBIO' )
end
function p.fastLink( id, label )
--P2163's format regex: [1-9]\d{0,7} (e.g. 1916996)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://id.worldcat.org/fast/'..id..'/ '..(label or 'Faceted Application of Subject Terminology')..']'..p.getCatForId( 'FAST' )
end
function p.fnzaLink( id, label )
--P6792's format regex: [1-9]\d* (e.g. 9785)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://findnzartists.org.nz/artist/'..id..'/ '..(label or 'New Zealand Artists')..']'..p.getCatForId( 'FNZA' )
end
function p.gndLink( id, label )
--P227's format regex: 1[012]?\d{7}[0-9X]|[47]\d{6}-\d|[1-9]\d{0,7}-[0-9X]|3\d{7}[0-9X] (e.g. 4079154-3)
if not id:match( '^1[012]?%d%d%d%d%d%d%d[0-9X]$' ) and
not id:match( '^[47]%d%d%d%d%d%d%-%d$' ) and
not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
not id:match( '^3%d%d%d%d%d%d%d[0-9X]$' ) then
return false
end
return '[https://d-nb.info/gnd/'..id..' '..(label or 'Germany')..']'..p.getCatForId( 'GND' )
end
function p.googleLink( id, label )
--P1960's format regex: [-_0-9A-Za-z]{12} (e.g. CUO0vDcAAAAJ)
if not id:match( '^[%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u]$' ) then
return false
end
return '[https://scholar.google.com/citations?user='..id..' '..(label or 'Google Scholar')..']'..p.getCatForId( 'Google Scholar' )
end
function p.hdsLink( id, label )
--P902's format regex: \d{6} (e.g. 050123)
if not id:match( '^%d%d%d%d%d%d$' ) then
return false
end
return '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..(label or 'Historical Dictionary of Switzerland')..']'..p.getCatForId( 'HDS' )
end
function p.iaafLink( id, label )
--P1146's format regex: [0-9][0-9]* (e.g. 012)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.iaaf.org/athletes/_/'..id..' '..(label or 'World Athletics')..']'..p.getCatForId( 'IAAF' )
end
function p.iccuLink( id, label )
--P396's format regex: \D{2}[A-Z0-3]V\d{6} (e.g. CFIV000163)
if not id:match( '^%u%u[%u0-3]V%d%d%d%d%d%d$' ) then --legacy: %u used here instead of %D (but the faulty ID cat is empty, out of ~12k uses)
return false
end
return '[https://opac.sbn.it/nome/'..id..' '..(label or 'Italy')..']'..p.getCatForId( 'ICCU' )
end
function p.iciaLink( id, label )
--P1736's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..(label or 'ICIA (Israel)')..']'..p.getCatForId( 'ICIA' )
end
function p.ieuLink( id, label )
--P9070's format regex: [A-Z]\\[A-Z]\\[A-Za-z0-9]+ (e.g. K\Y\Kyiv)
if not id:match( '^[A-Z]\\[A-Z]\\%w+$' ) then
return false
end
return '[http://www.encyclopediaofukraine.com/display.asp?linkpath=pages\\'..id..' '..(label or 'Internet Encyclopedia of Ukraine')..']'..p.getCatForId( 'IEU' )
end
function p.isniLink( id, label )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return '[https://isni.org/isni/'..id..' '..(label or 'ISNI')..']'..p.getCatForId( 'ISNI' )
end
function p.j9uLink( id, label )
--P8189's format regex: 9870(0|1)\d{8}05171 (e.g. 987007305652505171)
if not id:match( '^9870[0-1]%d%d%d%d%d%d%d%d05171$' ) then
return false
end
return '[http://uli.nli.org.il/F/?func=find-b&local_base=NLX10&find_code=UID&request='..id..' '..(label or 'Israel')..']'..p.getCatForId( 'J9U' )
end
function p.jocondeLink( id, label )
--P347's format regex: [\-0-9A-Za-z]{11} (e.g. 12345678901)
local regex = '^'..string.rep('[%-0-9A-Za-z]', 11)..'$'
if not id:match( regex ) then
return false
end
return '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..(label or 'Joconde (France)')..']'..p.getCatForId( 'Joconde' )
end
function p.kulturnavLink( id, label )
--P1248's format regex: [0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[http://kulturnav.org/'..id..' '..(label or 'KulturNav (Norway)')..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end
function p.lccnLink( id, label )
local parts = p.splitLccn( id ) --e.g. n78039510
if not parts then
return false
end
local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
id = parts[1] .. parts[2] .. p.append( parts[3], '0', 6 )
return '[https://id.loc.gov/authorities/'..lccnType..'/'..id..' '..(label or 'United States')..']'..p.getCatForId( 'LCCN' )
end
function p.lirLink( id, label )
--P886's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..(label or 'Lexicon Istoric Retic (Switzerland)')..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end
function p.lnbLink( id, label )
--P1368's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..(label or 'Latvia')..']'..p.getCatForId( 'LNB' )
end
function p.marinaMilitareLink( id, label )
--P3863's format regex: [1-9]\d* (e.g. 3856)
if id:match( '^[1-9]%d*$' ) then
return '[http://www.marina.difesa.it/cosa-facciamo/per-la-difesa-sicurezza/fari/Pagine/'..id..'.aspx '..(label or 'Italy')..']'..p.getCatForId( 'Marina Militare' )
else
return false
end
end
function p.mathsnLink( id, label )
--P4955's format regex: [1-9]\d{4,6} (e.g. 175270)
if not id:match( '^[1-9]%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://mathscinet.ams.org/mathscinet/MRAuthorID/'..id..' '..(label or 'MathSciNet')..']'..p.getCatForId( 'MATHSN' )
end
function p.mbaLink( id, label )
--P434's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/artist/'..id
local cat = p.getCatForId( 'MusicBrainz' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBA (identifier)|MusicBrainz]] ['..url..' artist]'..cat
end
end
function p.mbareaLink( id, label )
--P982's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/area/'..id
local cat = p.getCatForId( 'MusicBrainz area' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBAREA (identifier)|MusicBrainz]] ['..url..' area]'..cat
end
end
function p.mbiLink( id, label )
--P1330's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/instrument/'..id
local cat = p.getCatForId( 'MusicBrainz instrument' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBI (identifier)|MusicBrainz]] ['..url..' instrument]'..cat
end
end
function p.mblLink( id, label )
--P966's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/label/'..id
local cat = p.getCatForId( 'MusicBrainz label' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBL (identifier)|MusicBrainz]] ['..url..' label]'..cat
end
end
function p.mbpLink( id, label )
--P1004's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/place/'..id
local cat = p.getCatForId( 'MusicBrainz place' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBP (identifier)|MusicBrainz]] ['..url..' place]'..cat
end
end
function p.mbrgLink( id, label )
--P436's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/release-group/'..id
local cat = p.getCatForId( 'MusicBrainz release group' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBRG (identifier)|MusicBrainz]] ['..url..' release group]'..cat
end
end
function p.mbsLink( id, label )
--P1407's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/series/'..id
local cat = p.getCatForId( 'MusicBrainz series' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBS (identifier)|MusicBrainz]] ['..url..' series]'..cat
end
end
function p.mbwLink( id, label )
--P435's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/work/'..id
local cat = p.getCatForId( 'MusicBrainz work' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBW (identifier)|MusicBrainz]] ['..url..' work]'..cat
end
end
function p.mgpLink( id, label )
--P549's format regex: \d{1,6} (e.g. 123456)
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://www.mathgenealogy.org/id.php?id='..id..' '..(label or 'Mathematics Genealogy Project')..']'..p.getCatForId( 'MGP' )
end
function p.mtLink( id, label )
--P3601's format regex: \d{10} (e.g. 1000004707)
if id:match( '^%d%d%d%d%d%d%d%d%d%d$' ) then
return '[https://www.marinetraffic.com/en/ais/details/lights/'..id..' '..(label or 'MarineTraffic')..']'..p.getCatForId( 'MarineTraffic' )
else
return false
end
end
function p.naraLink( id, label )
--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://catalog.archives.gov/id/'..id..' '..(label or 'National Archives (US)')..']'..p.getCatForId( 'NARA' )
end
function p.nclLink( id, label )
--P1048's format regex: \d+ (e.g. 1081436)
if not id:match( '^%d+$' ) then
return false
end
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..(label or 'Taiwan')..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019
end
function p.ndlLink( id, label )
--P349's format regex: 0?\d{8} (e.g. 012345678)
if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..(label or 'Japan')..']'..p.getCatForId( 'NDL' )
end
function p.ngaLink(id,label)
--P3563's format rgex: 11[0-6]-\d+(\.\d+)? (e.g. 114-7721.2)
if not id:match('^11[0-6]%-%d+%.?%d*$') then
return false
end
return '[https://wikidata-externalid-url.toolforge.org/?url=https%3A%2F%2Fmsi.nga.mil%2FqueryResults%3Fpublications%2Fngalol%2Flights-buoys%3Fvolume%3D%251%26featureNumber%3D%252%26includeRemovals%3Dfalse%26output%3Dhtml&exp=(%5Cd%7B3%7D)-(.*)&id='..id..' '..(label or 'NGA')..']'..p.getCatForId( 'NGA' )
end
function p.ngvLink( id, label )
--P2041's format regex: \d+ (e.g. 12354)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..(label or 'Victoria')..']'..p.getCatForId( 'NGV' )
end
function p.nkcLink( id, label )
--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
if not id:match( '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..(label or 'Czech Republic')..']'..p.getCatForId( 'NKC' )
end
function p.nlaLink( id, label )
--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://nla.gov.au/anbd.aut-an'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'NLA' )
end
function p.nlgLink( id, label )
--P3348's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://data.nlg.gr/resource/authority/record'..id..' '..(label or 'Greece')..']'..p.getCatForId( 'NLG' )
end
function p.nlkLink( id, label )
--P5034's format regex: (KAB|KAC|KSH)([0-9]{4}|[0-9]{4}[a-zA-Z])[0-9]{4,6} (e.g. KAC201501465)
if not id:match( '^KAB%d%d%d%d%a?%d%d%d%d%d?%d?$' ) and
not id:match( '^KAC%d%d%d%d%a?%d%d%d%d%d?%d?$' ) and
not id:match( '^KSH%d%d%d%d%a?%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://lod.nl.go.kr/resource/'..id..' '..(label or 'Korea')..']'..p.getCatForId( 'NLK' )
end
function p.nlpLink( id, label )
--P1695's format regex: 9810[0-9]\d* or A[0-9]{7}[0-9X] (e.g. 9810123456789012345 or A10414836)
if not id:match( '^9810%d+$' ) and
not id:match( '^A%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'NLP' )
end
function p.nlrLink( id, label )
--P1003's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://aleph.bibnat.ro:8991/F/?func=direct&local_base=NLR10&doc_number='..id..' '..(label or 'Romania')..']'..p.getCatForId( 'NLR' )
end
function p.nskLink( id, label )
--P1375's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..(label or 'Croatia')..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end
function p.ntaLink( id, label )
--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)
if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[http://data.bibliotheken.nl/id/thes/p'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'NTA' )
end
function p.orcidLink( id, label )
id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483
if not id then
return false
end
id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
return '[https://orcid.org/'..id..' '..(label or 'ORCID')..']'..p.getCatForId( 'ORCID' )
end
function p.picLink( id, label )
--P2750's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://pic.nypl.org/constituents/'..id..' '..(label or 'Photographers\' Identities')..']'..p.getCatForId( 'PIC' )
end
function p.plwabnLink( id, label )
--P7293's format regex: 981[0-9]{8}05606 (e.g. 9810696457305606)
if not id:match( '^981%d%d%d%d%d%d%d%d05606*$' ) then
return false
end
return '[http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=1&NU=1&IM=4&WI='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'PLWABN' )
end
function p.publonsLink( id, label )
--P3829's format regex: \d+ (e.g. 654601)
if not id:match( '^%d+$' ) then
return false
end
return '[https://publons.com/author/'..id..'/ '..(label or 'Publons (researchers)')..']'..p.getCatForId( 'Publons' )
end
function p.ridLink( id, label )
--P1053's format regex: [A-Z]{1,3}-\d{4}-(19|20)\d\d (e.g. AAS-5150-2020)
if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-19%d%d$' ) and
not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20%d%d$' ) then
return false
end
return '[https://www.researcherid.com/rid/'..id..' '..(label or 'ResearcherID')..']'..p.getCatForId( 'RID' )
end
function p.rismLink( id, label )
--P5504's format regex: (pe|ks)?\[1-9]d* (e.g. pe30006410)
if not id:match( '^pe[1-9]%d*$' ) and --99% start with 'pe'
not id:match( '^ks[1-9]%d*$' ) and
not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://opac.rism.info/search?id='..id..' '..(label or 'RISM (France)')..']'..p.getCatForId( 'RISM' )
end
function p.reroLink( id, label )
--P3065's format regex: 0[1-2]-[A-Z0-9]{1,10} (e.g. 02-A012345678)
if not id:match( '^0[1-2]%-[A-Z%d][A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?$' ) then
return false
end
return '[http://data.rero.ch/'..id..' '..(label or 'RERO (Switzerland)')..']'..p.getCatForId( 'RERO' )
end
function p.rkdartistsLink( id, label )
--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/en/explore/artists/'..id..' '..(label or 'RKD Artists (Netherlands)')..']'..p.getCatForId( 'RKDartists' )
end
function p.rkdidLink( id, label )
--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/nl/explore/images/'..id..' '..(label or 'RKD ID (Netherlands)')..']'..p.getCatForId( 'RKDID' )
end
function p.rslLink( id, label )
--P947's format regex: \d{1,9} (e.g. 123456789)
if not id:match( '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..(label or 'Russia')..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019
end
function p.scopusLink( id, label )
--P1153's format regex: [1-9]\d{9,10} (e.g. 35247902700)
if not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d?$' ) then
return false
end
return '[https://www.scopus.com/authid/detail.uri?authorId='..id..' '..(label or 'Scopus author')..']'..p.getCatForId( 'Scopus' )
end
function p.selibrLink( id, label )
--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
if not id:match( '^[1-9]%d%d%d%d%d?$' ) then
return false
end
return '[https://libris.kb.se/auth/'..id..' '..(label or 'Sweden')..']'..p.getCatForId( 'SELIBR' )
end
function p.sikartLink( id, label )
--P781's format regex: \d{7,9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) then
return false
end
return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..(label or 'SIKART (Switzerland)')..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019
end
function p.snacLink( id, label )
--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
return false
end
return '[https://snaccooperative.org/ark:/99166/'..id..' '..(label or 'Social Networks and Archival Context')..']'..p.getCatForId( 'SNAC-ID' )
end
function p.sudocLink( id, label )
--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)
if not id:match( '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'
return false
end
return '[https://www.idref.fr/'..id..' '..(label or 'SUDOC (France)')..']'..p.getCatForId( 'SUDOC' )
end
function p.ta98Link( id, label )
--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
return false
end
local longurl = '[http://tools.wmflabs.org/wikidata-externalid-url/?p=1323&url_prefix=https:%2F%2Fwww.unifr.ch%2Fifaa%2FPublic%2FEntryPage%2FTA98%20Tree%2FEntity%20TA98%20EN%2F&url_suffix=%20Entity%20TA98%20EN.htm&id='
return longurl..id..' '..(label or 'Terminologia Anatomica')..']'..p.getCatForId( 'TA98' )
end
function p.tdviaLink( id, label )
--P7314's format regex: [0-9a-z/-]+] (e.g. barkan-omer-lutfi)
if not id:match( '^[%d%l/-]+$' ) then
return false
end
return '[https://islamansiklopedisi.org.tr/'..id..' '..(label or 'İslâm Ansiklopedisi')..']'..p.getCatForId( 'TDVİA' )
end
function p.tepapaLink( id, label )
--P3544's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://collections.tepapa.govt.nz/agent/'..id..' '..(label or 'Te Papa (New Zealand)')..']'..p.getCatForId( 'TePapa' )
end
function p.tlsLink( id, label )
id = id:gsub(' +', '_')
--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*\/–&]{3,89} (e.g. Abcd)
--Mediawiki page title partial URL so consider validation with mw.title or "[^#<>%[%] {|}]"
local class = "[%w_',%.%-%(%)%*%/–&]"
local idlen = mw.ustring.len (id)
if idlen < 4 or idlen > 90 then
return false
end
local regex = '^%u'..string.rep(class, idlen - 1)..'$'
if not mw.ustring.match( id, regex ) then
return false
end
return '[http://tls.theaterwissenschaft.ch/wiki/'..id..' '..(label or 'Theaterlexikon (Switzerland)')..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019
end
function p.troveLink( id, label )
--P1315's format regex: [1-9]\d{5,7} (e.g. 12345678)
if not id:match( '^[1-9]%d%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://trove.nla.gov.au/people/'..id..' '..(label or 'Trove (Australia)')..']'..p.getCatForId( 'Trove' )
end
function p.ukparlLink( id, label )
--P6213's format regex: [a-zA-Z\d]{8} (e.g. AQUupyiR)
if not id:match( '^[a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d]$' ) then
return false
end
return '[https://id.parliament.uk/'..id..' '..(label or 'UK Parliament')..']'..p.getCatForId( 'UKPARL' )
end
function p.ulanLink( id, label )
--P245's format regex: 500\d{6} (e.g. 500123456)
if not id:match( '^500%d%d%d%d%d%d$' ) then
return false
end
return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..(label or 'Artist Names (Getty)')..']'..p.getCatForId( 'ULAN' )
end
function p.uscgLink( id, label )
--P3723's format regex: [1-7]-\d{1,5}(.[1-9])? (e.g. 6-0695)
if not id:match( '^[1-7]%-%d%d?%d?%d?%d?$' ) and
not id:match( '^[1-7]%-%d%d?%d?%d?%d?%.%d*[1-9]$' ) then
return false
end
return '[[USCG (identifier)|USCG]] ([https://www.navcen.uscg.gov/pdf/lightlists/LightList%20V'..mw.ustring.sub(id,1,1)..'.pdf '..id..'])'..p.getCatForId( 'USCG' )
end
function p.uscongressLink( id, label )
--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
if not id:match( '^[A-Z]00[01]%d%d%d$' ) then
return false
end
return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..(label or 'US Congress')..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019
end
function p.vcbaLink( id, label )
--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)
if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
id = id:gsub('\/', '_')
return '[https://opac.vatlib.it/auth/detail/'..id..' '..(label or 'Vatican')..']'..p.getCatForId( 'VcBA' )
end
function p.viafLink( id, label )
--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)
if not id:match( '^[1-9]%d%d?%d?%d?%d?%d?%d?%d?$' ) and
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d?%d?%d?$' ) then
return false
end
-- If the "VIAF" entry at [[:m:Interwiki map]] would resolve to "https://viaf.org/viaf/$1" (rather than "http://viaf.org/viaf/$1", as it currently still does),
-- then the code below could change from '[https://viaf.org/viaf/'..id..' '..id..']' to '[[:VIAF:'..id..'|'..id..']]'.
return '[https://viaf.org/viaf/'..id..' '..(label or 'VIAF')..']'..p.getCatForId( 'VIAF' )
end
function p.worldcatidLink( id, label )
--P7859's format regex: viaf-\d+|lccn-n[a-z]?[0-9\-]+|n[cps]-.+ (e.g. viaf-100181709, lccn-n78-95332, np-verbeck,%20william$1861)
if not id:match( '^viaf%-%d+$' ) and
not id:match( '^lccn%-n[a-z]?[0-9%-]+$' ) and
not id:match( '^n[cps]%-.+$' ) then
return false
end
return '[https://www.worldcat.org/identities/'..mw.uri.encode(id, 'PATH')..'/ '..(label or 'WorldCat')..']'..p.getCatForId( 'WORLDCATID' )
end
function p.zbmathLink( id, label )
--P1556's format regex: [a-z][a-z\-]*(\.[a-z][a-z\-]*)?(\.[0-9]*)? (e.g. turing.alan-m)
local ps = {'%l[%l%-]*', '%.%l[%l%-]*', '%.%d*'}
if not id:match( '^'..ps[1]..'$' ) and -- prefix with no capture options
not id:match( '^'..ps[1]..ps[2]..'$' ) and -- prefix with first capture option
not id:match( '^'..ps[1]..ps[3]..'$' ) and -- prefix with second capture option
not id:match( '^'..ps[1]..ps[2]..ps[3]..'$' ) then -- prefix and both capture options
return false
end
return '[https://zbmath.org/authors/?q=ai:'..id..' '..(label or 'zbMATH')..']'..p.getCatForId( 'ZBMATH' )
end
--[[=========================== Helper functions =============================]]
function p.append(str, c, length)
while str:len() < length do
str = c..str
end
return str
end
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
function p.getIsniCheckDigit( isni )
local total = 0
for i = 1, 15 do
local digit = isni:byte( i ) - 48 --Get integer value
total = (total + digit) * 2
end
local remainder = total % 11
local result = (12 - remainder) % 11
if result == 10 then
return 'X'
end
return tostring( result )
end
--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function p.validateIsni( id )
--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)
--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)
id = id:gsub( '[ %-]', '' ):upper()
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
return false
end
return id
end
function p.splitLccn( id )
--P244's format regex: (n|nb|nr|no|ns|sh)([4-9][0-9]|00|20[0-1][0-9])[0-9]{6} (e.g. n78039510)
if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
end
if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
return mw.text.split( id, '/' )
end
return false
end
--[[==========================================================================]]
--[[ Wikidata & documentation functions ]]
--[[==========================================================================]]
function p.getIdsFromWikidata( itemId, property )
local ids = {}
if not mw.wikibase then
return ids
end
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
table.insert( ids, statement.mainsnak.datavalue.value )
end
end
end
return ids
end
function p.checkcat( category,label )
local ret='[[:Category:'..category..'|'..label..']]'
if mw.title.new(category, 14).exists == false then
ret = ret..' <span class="plainlinks" style="font-size:85%;">[['..tostring(mw.uri.fullUrl('Category:'..category,'action=edit&preload=Template:Authority_control/preload'))..' create]]</span>'
end
return ret
end
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
function p.docConfTable( frame )
local wikiTable = '<table class="wikitable sortable">'..
'<tr><th rowspan=2>Parameter</th>'..
'<th rowspan=2>Section</th>'..
'<th rowspan=2>Appears as</th>'..
'<th rowspan=2 data-sort-type=number>Wikidata property</th>'..
'<th colspan=2>Tracking categories and page counts</th></tr>'..
'<tr><th>[[:Category:Articles with authority control information|Articles]]</th>'..
'<th>[[:Category:Articles with faulty authority control information|Faulty IDs]]</th></tr>'
local lang = mw.getContentLanguage()
local a, f, P = 0, 0, 0 --cumulative sums
for _, conf in pairs( p.conf ) do
local param, pid, section = conf[1], conf[2], conf[4]
local appearsAs
if conf.prefix then
appearsAs = conf.prefix
else
appearsAs = conf[3](conf[5])
end
local link = conf.link or param..' (identifier)'
local category = conf.category or param
local args = { id = 'f', pid }
local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }
--cats
local articleCat = 'Articles with '..category..' identifiers'
local faultyCat = 'Articles with faulty '..category..' identifiers'
--counts
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
local faultyCount = lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )
--calcs
P = P + 1 --property count
a = a + lang:parseFormattedNumber(articleCount)
f = f + lang:parseFormattedNumber(faultyCount)
--concat
wikiTable = wikiTable..'<tr><td>[['..link..'|'..param..']]</td>'..
'<td>'..section..'</td>'..
'<td>'..appearsAs..'</td>'..
'<td data-sort-value='..pid..'>'..wpl..'</td>'..
'<td style="text-align: right;">'..p.checkcat(articleCat,articleCount)..'</td>'..
'<td style="text-align: right;">'..p.checkcat(faultyCat,faultyCount)..'</td></tr>'
end
--append derivative WorldCat cats
local wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' }
for _, w in pairs(wcd) do
local articleCat = 'Articles with '..w..' identifiers'
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
local appearsAs
if w == 'WorldCat-LCCN' then
appearsAs = '[https://www.worldcat.org/identities/lccn-n79-113947 WorldCat (via Library of Congress)]'
else
appearsAs = '[https://www.worldcat.org/identities/containsVIAFID/12345789 WorldCat (via VIAF)]'
end
a = a + lang:parseFormattedNumber(articleCount)
wikiTable = wikiTable..'<tr><td>-</td>'..
'<td>General</td>'..
'<td>'..appearsAs..'</td>'..
'<td data-sort-value='..w..'>—</td>'..
'<td style="text-align: right;">[[:Category:'..articleCat..'|'..articleCount..']]</td>'..
'<td style="text-align: right;">—</td></tr>'
end
--append sums
wikiTable = wikiTable..'<tr><th style="text-align: right;" colspan=3>Totals</th>'..
'<th style="text-align: right;">'..lang:formatNum(P)..'</th>'..
'<th style="text-align: right;">'..lang:formatNum(a)..'</th>'..
'<th style="text-align: right;">'..lang:formatNum(f)..'</th></tr></table>'
return require('Module:Suppress categories').main(wikiTable)
end
--[[==========================================================================]]
--[[ Configuration ]]
--[[==========================================================================]]
-- Please use "<parameter> (identifier)" redirects rather than linking directly to the target page.
-- This reduces clutter in "What links here" on both the redirect and the target,
-- and improves reverse lookup of articles where a manifestation of each identifier is used.
-- p.conf table basic format: { 'parameter name', propertyId # in Wikidata, formatting/validation function, section, example ID for documentation }
-- p.conf table optional named parameters:
-- link: to override the link in the documentation (defaults to "<parameter> (identifer)")
-- category: to override the ID in category names (defaults to "... with <parameter> identifiers")
-- prefix: to include a prefix (usually a wikilink explaining what the identifier is) before the external link itself
p.conf = {
{ 'AAG', 3372, p.aagLink, 'Art galleries and museums', '1' },
{ 'ACM-DL', 864, p.acmLink, 'Scientific databases', '12345678901', link = 'ACM DL (identifier)' },
{ 'ADB', 1907, p.adbLink,'Biographical dictionaries', 'barton-sir-edmund-toby-71' },
{ 'admiralty', 3562, p.admiraltyLink, 'Lighthouse identifiers', 'D1204.1', prefix='[[Admiralty number|Admiralty]]'},
{ 'AGSA', 6804, p.agsaLink, 'Art galleries and museums', '3625' },
{ 'ARLHS', 2980, p.ARLHSLink, 'Lighthouse identifiers', 'LAT023'},
{ 'autores.uy', 2558, p.autoresuyLink, 'Biographical dictionaries', '12345' },
{ 'AWR', 4186, p.awrLink, 'Biographical dictionaries', 'PR00768b' },
{ 'BIBSYS', 1015, p.bibsysLink, 'National libraries', '1234567890123' },
{ 'Bildindex', 2092, p.bildLink, 'Art research institutes', '1' },
{ 'BNC', 1890, p.bncLink, 'National libraries', '123456789' },
{ 'BNE', 950, p.bneLink, 'National libraries', 'XX1234567' },
{ 'BNF', 268, p.bnfLink, 'National libraries', '123456789' },
{ 'BNMM', 3788, p.bnmmLink, 'National libraries', '000024044' },
{ 'Botanist', 428, p.botanistLink , 'Scientific databases', 'L.' },
{ 'BPN', 651, p.bpnLink , 'Biographical dictionaries', '12345678' },
{ 'CANTIC', 1273, p.canticLink, 'National libraries', 'a12345678' },
{ 'CANTICN', 9984, p.canticnLink, 'National libraries', '981058515460906706' },
{ 'CCG', 3920, p.ccgLink, 'Lighthouse identifiers', 'A1761', prefix='[[CCG (identifier)|CCG]]' },
{ 'CINII', 271, p.ciniiLink, 'Scientific databases', 'DA12345678', link = 'CiNii (identifier)' },
{ 'CWGC', 1908, p.cwgcLink, 'Other', '1234567' },
{ 'DAAO', 1707, p.daaoLink, 'Art research institutes', 'rolf-harris' },
{ 'DBLP', 2456, p.dblpLink, 'Scientific databases', '123/123' },
{ 'DIB', 6829, p.dibLink, 'Biographical dictionaries', '001953' },
{ 'DSI', 2349, p.dsiLink, 'Art research institutes', '1538' },
{ 'DTBIO', 7902, p.dtbioLink, 'Biographical dictionaries', '118554700' },
{ 'EMU', 4613, p.emuLink, 'National libraries', '15409' },
{ 'FAST', 2163, p.fastLink, 'Other', '1' },
{ 'FNZA', 6792, p.fnzaLink, 'Art research institutes', '12' },
{ 'GND', 227, p.gndLink, 'National libraries', '4079154-3' },
{ 'Google Scholar', 1960, p.googleLink, 'Scientific databases', 'QPdLuj8AAAAJ' },
{ 'HDS', 902, p.hdsLink, 'Other', '050123' },
{ 'IAAF', 1146, p.iaafLink, 'Other', '123' },
{ 'ICCU', 396, p.iccuLink, 'National libraries', 'CFIV000163' }, --formerly SBN
{ 'ICIA', 1736, p.iciaLink, 'Art research institutes', '1' },
{ 'IEU', 9070, p.ieuLink, 'Other', 'N\\A\\NationalAcademyofArtandArchitecture' },
{ 'ISNI', 213, p.isniLink, 'General', '0000-0000-6653-4145', prefix = '[[ISNI (identifier)|ISNI]]' },
{ 'J9U', 8189, p.j9uLink, 'National libraries', '987007305652505171' },
{ 'Joconde', 347, p.jocondeLink, 'Art research institutes', '12345678901' },
{ 'KULTURNAV', 1248, p.kulturnavLink, 'Art research institutes', '12345678-1234-1234-1234-1234567890AB', link = 'KulturNav (identifier)' },
{ 'LCCN', 244, p.lccnLink, 'National libraries', 'n78039510' },
{ 'LIR', 886, p.lirLink, 'Other', '1' },
{ 'LNB', 1368, p.lnbLink, 'National libraries', '123456789' },
{ 'Marina Militare', 3863, p.marinaMilitareLink, 'Lighthouse identifiers', '3856' },
{ 'MarineTraffic', 3601, p.mtLink, 'Lighthouse identifiers', '1000004707' },
{ 'MATHSN', 4955, p.mathsnLink, 'Scientific databases', '175270' },
{ 'MBA', 434, p.mbaLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz' }, --special cat name
{ 'MBAREA', 982, p.mbareaLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz area' }, --special cat name
{ 'MBI', 1330, p.mbiLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz instrument' }, --special cat name
{ 'MBL', 966, p.mblLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz label' }, --special cat name
{ 'MBP', 1004, p.mbpLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz place' }, --special cat name
{ 'MBRG', 436, p.mbrgLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz release group' }, --special cat name
{ 'MBS', 1407, p.mbsLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz series' }, --special cat name
{ 'MBW', 435, p.mbwLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz work' }, --special cat name
{ 'MGP', 549, p.mgpLink, 'Scientific databases', '123456' },
{ 'NARA', 1225, p.naraLink, 'Other', '12345678' },
{ 'NCL', 1048, p.nclLink, 'National libraries', '1081436' },
{ 'NDL', 349, p.ndlLink, 'National libraries', '012345678' },
{ 'NGA', 3563, p.ngaLink, 'Lighthouse identifiers', '114-5592'},
{ 'NGV', 2041, p.ngvLink, 'Art galleries and museums', '12354' },
{ 'NKC', 691, p.nkcLink, 'National libraries', 'abcd12345678901234' },
{ 'NLA', 409, p.nlaLink, 'National libraries', '123456789012' },
{ 'NLG', 3348, p.nlgLink, 'National libraries', '12345678' },
{ 'NLK', 5034, p.nlkLink, 'National libraries', 'KAB197000000' },
{ 'NLP', 1695, p.nlpLink, 'National libraries', '9810123456789012345' },
{ 'NLR', 1003, p.nlrLink, 'National libraries', '123456789' },
{ 'NSK', 1375, p.nskLink, 'National libraries', '123456789' },
{ 'NTA', 1006, p.ntaLink, 'National libraries', '12345678X' },
{ 'ORCID', 496, p.orcidLink, 'General', '0000-0002-7398-5483', prefix = '[[ORCID (identifier)|ORCID]]' },
{ 'PIC', 2750, p.picLink, 'Art research institutes', '1' },
{ 'PLWABN', 7293, p.plwabnLink, 'National libraries', '9812345678905606' },
{ 'Publons', 3829, p.publonsLink, 'Scientific databases', '2776255' },
{ 'RID', 1053, p.ridLink, 'Scientific databases', 'A-1234-1934' },
{ 'RISM', 5504, p.rismLink, 'Other', 'pe1', prefix = '[[RISM (identifier)|RISM (France)]]' },
{ 'RERO', 3065, p.reroLink, 'Other', '02-A012345678', prefix = '[[RERO (identifier)|RERO (Switzerland)]]' },
{ 'RKDartists', 650, p.rkdartistsLink, 'Art research institutes', '123456' },
{ 'RKDID', 350, p.rkdidLink, 'Art research institutes', '123456' },
{ 'RSL', 947, p.rslLink, 'National libraries', '123456789' },
{ 'Scopus', 1153, p.scopusLink, 'Scientific databases', '7005487412' },
{ 'SELIBR', 906, p.selibrLink, 'National libraries', '123456' },
{ 'SIKART', 781, p.sikartLink, 'Art research institutes', '123456789' },
{ 'SNAC-ID', 3430, p.snacLink, 'Other', 'A' },
{ 'SUDOC', 269, p.sudocLink, 'Other', '026927608', prefix = '[[SUDOC (identifier)|SUDOC (France)]]' },
{ 'TA98', 1323, p.ta98Link, 'Scientific databases', 'A12.3.45.678' },
{ 'TDVİA', 7314, p.tdviaLink, 'Other', 'asim-b-behdele' },
{ 'TePapa', 3544, p.tepapaLink, 'Art galleries and museums', '1' },
{ 'TLS', 1362, p.tlsLink, 'Other', 'Abcd' },
{ 'Trove', 1315, p.troveLink, 'Other', '12345678', prefix = '[[Trove (identifier)|Trove (Australia)]]' }, --formerly NLA-person
{ 'UKPARL', 6213, p.ukparlLink, 'Other', 'AQUupyiR' },
{ 'ULAN', 245, p.ulanLink, 'Art research institutes', '500123456' },
{ 'USCG', 3723, p.uscgLink, 'Lighthouse identifiers', '6-0695'},
{ 'USCongress', 1157, p.uscongressLink, 'Other', 'A000123', link = 'US Congress (identifier)' },
{ 'VcBA', 8034, p.vcbaLink, 'National libraries', '494/9793' },
{ 'VIAF', 214, p.viafLink, 'General', '123456789', prefix = '[[VIAF (identifier)|VIAF]]' },
{ 'WORLDCATID', 7859, p.worldcatidLink, 'General', 'lccn-n78-95332', link = 'WorldCat Identities (identifier)' },
{ 'ZBMATH', 1556, p.zbmathLink, 'Scientific databases', 'turing.alan-m' },
}
-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
{ 'DNB', 'GND' }, --Deutsche Nationalbibliothek -> Gemeinsame Normdatei
{ 'MusicBrainz', 'MBA' },
{ 'MusicBrainz artist', 'MBA' },
{ 'MusicBrainz label', 'MBL' },
{ 'MusicBrainz release group', 'MBRG' },
{ 'MusicBrainz work', 'MBW' },
{ 'SBN', 'ICCU' }, --SBN alias to be deprecated at a later stage
{ 'TDVIA', 'TDVİA' }, --alias name without diacritics
{ 'tdvia', 'TDVİA' }, --lowercase variant without diacritics
}
-- Deprecated aliases to p.conf; tracked in [[Category:Articles with deprecated authority control identifiers]]
-- Format: { 'deprecated parameter name', 'replacement parameter name in p.conf' }
p.deprecated = {
{ 'GKD', 'GND' },
{ 'PND', 'GND' },
{ 'RLS', 'RSL' },
{ 'SWD', 'GND' },
{ 'NARA-organization', 'NARA' },
{ 'NARA-person', 'NARA' },
}
--[[==========================================================================]]
--[[ Main ]]
--[[==========================================================================]]
function p.authorityControl( frame )
local resolveEntity = require( 'Module:ResolveEntityId' )
local parentArgs = frame:getParent().args --WD IDs added here later
local iParentArgs = 0 --count original/manual parent args only later
local worldcatCat = ''
local elementsCat = ''
local multipleIdCat = ''
local suppressedIdCat = ''
local suppressedIdCatArts = ''
local deprecatedIdCat = ''
local differentOnWDCat = ''
local sameOnWDCat = ''
local stateCat = ''
--redirect aliases to proper parameter names
for _, a in pairs( p.aliases ) do
local alias, param = a[1], a[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
parentArgs[param] = parentArgs[alias]
end
end
--redirect deprecated parameters to proper parameter names, and assign tracking cat
for _, d in pairs( p.deprecated ) do
local dep, param = d[1], d[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
parentArgs[param] = parentArgs[dep]
if namespace == 0 then
deprecatedIdCat = '[[Category:Articles with deprecated authority control identifiers|'..dep..']]'
end
end
end
--use QID= parameter for testing/example purposes only
local itemId = nil
if namespace ~= 0 then
local qid = parentArgs['qid'] or parentArgs['QID']
if qid then
itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
itemId = resolveEntity._id(itemId) --nil if unresolvable
end
elseif mw.wikibase then
itemId = mw.wikibase.getEntityIdForCurrentPage()
end
--Wikidata fallback if available
if itemId then
local suppressedIdCount = 0
local iMatches = 0
for _, params in ipairs( p.conf ) do
if params[2] > 0 then
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val == nil or val == '' then
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
if wikidataIds[1] then
if val == '' and (namespace == 0 or testcases) then
suppressedIdCount = suppressedIdCount + 1
suppressedIdCat = '[[Category:Articles with suppressed authority control identifiers|'..params[1]..']]'
else
parentArgs[params[1]] = wikidataIds[1] --add ID from WD
end
end
else
iParentArgs = iParentArgs + 1
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
if wikidataIds[1] and differentOnWDCat == '' then
local bMatch = false
for _, wd in pairs( wikidataIds ) do
if val == wd then
iMatches = iMatches + 1
bMatch = true
end
end
if bMatch == false then
differentOnWDCat = '[[Category:Pages using authority control with parameters different on Wikidata|'..params[1]..']]'
end end end end end
if iMatches > 0 and iMatches == iParentArgs then
sameOnWDCat = '[[Category:Pages using authority control with parameters all matching Wikidata]]'
end
if parentArgs['arts'] == 'arts' and suppressedIdCount > 0 then
if namespace == 0 or testcases then
local s = 's'
if suppressedIdCount == 1 then s = '' end
local sCat = 'ACArt with '..suppressedIdCount..' suppressed element'..s
suppressedIdCatArts = addCat(sCat)
end
end
end
--configure rows
local rct = 0
local sectionOrder = {
'General',
'National libraries',
'Art galleries and museums',
'Art research institutes',
'Biographical dictionaries',
'Scientific databases',
'Lighthouse identifiers',
'Other'
}
local sections = {
['General'] = {},
['National libraries'] = {},
['Art galleries and museums'] = {},
['Art research institutes'] = {},
['Biographical dictionaries'] = {},
['Scientific databases'] = {},
['Lighthouse identifiers'] = {},
['Other'] = {}
}
--don't show CANTIC if CANTICN is present, since they both go to the Library of Catalonia
--and the library has deprecated CANTIC IDs in favor of CANTICN IDs
if parentArgs.CANTICN or parentArgs.canticn then
parentArgs.CANTIC = ''
parentArgs.cantic = ''
end
--don't show NLP if PLWABN is present, since they both go to the National Library of Poland
--and the library has deprecated NLP IDs in favor of PLWABN IDs
if parentArgs.PLWABN or parentArgs.plwabn then
parentArgs.NLP = ''
parentArgs.nlp = ''
end
for _, params in ipairs( p.conf ) do
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
local tval, tlinks = {}, {} --init tables
if val and val ~= '' and type(params[3]) == 'function' then
table.insert( tval, val )
if params.prefix then
table.insert( tlinks, params[3]( val, '1' ) )
else
table.insert( tlinks, params[3]( val ) )
end
end
--collect other unique vals (IDs) from WD, if present
if itemId and tval[1] then
local nextIdVal = 2
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
for _, v in pairs( wikidataIds ) do
local bnew = true
for _, w in pairs( tval ) do
if v == w then bnew = false end
end
if bnew then
table.insert( tval, v )
table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )
nextIdVal = nextIdVal + 1
end
end
end
--assemble
if tval[1] then
table.insert( sections[params[4]], p.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )
rct = rct + 1
if tval[2] then
multipleIdCat = p.getCatForId( 'multiple' )
end
end
end
--WorldCat-VIAF & WorldCat-LCCN
local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
if worldcatId == nil then --if WORLDCATID absent but unsuppressed
local viafId = parentArgs['viaf'] or parentArgs['VIAF']
local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
table.insert( sections['General'], p.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' WorldCat (via VIAF)]', nil, false ) )
if namespace == 0 then
worldcatCat = '[[Category:Articles with WorldCat-VIAF identifiers]]'
end
rct = rct + 1
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
local lccnParts = p.splitLccn( lccnId )
if lccnParts and lccnParts[1] ~= 'sh' then
local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
table.insert( sections['General'], p.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' WorldCat (via Library of Congress)]', nil, false ) )
if namespace == 0 then
worldcatCat = '[[Category:Articles with WorldCat-LCCN identifiers]]'
end
end
rct = rct + 1
end
end
--configure Navbox
local outString = ''
local extrap = true
local extra = parentArgs.extralist
if extra == nil or extra == '' then
extrap = false
end
if rct > 0 or extrap then
local Navbox = require('Module:Navbox')
local sectionID = 1
local args = { pid = 'identifiers' } -- #target the list of identifiers
if testcases and itemId then args.qid = itemId end --expensive
local pencil = require('Module:EditAtWikidata')._showMessage(args)
local navboxArgs = {
name = 'Authority control',
navboxclass = 'authority-control',
bodyclass = 'hlist',
state = parentArgs.state or 'autocollapse',
navbar = 'off'
}
for _, sectName in ipairs(sectionOrder) do
if #sections[sectName] ~= 0 then
navboxArgs['group'..sectionID] = sectName
navboxArgs['list'..sectionID] = table.concat(sections[sectName])
sectionID = sectionID + 1
end
end
if extrap then
if parentArgs.extragroup then
navboxArgs['group'..sectionID] = parentArgs.extragroup
else
navboxArgs['group'..sectionID] = 'Additional'
end
navboxArgs['list'..sectionID] = extra
sectionID = sectionID + 1
end
if navboxArgs.list2 then
navboxArgs.title = '[[Help:Authority control|Authority control]]'..pencil
else
local sect = navboxArgs.group1
if sect == 'General' or sect == 'Other' or sect == 'Additional' then
-- Just say "Authority control" with no label if only general or only other IDs are present
-- since "general" is redundant and "other" is silly when there's nothing to contrast it with
navboxArgs.group1 = '[[Help:Authority control|Authority control]]'..pencil
else
navboxArgs.group1 = '[[Help:Authority control|Authority control: '..sect..']] '..pencil
end
end
outString = Navbox._navbox(navboxArgs)
end
--auxCats
if rct == 0 or rct >= 25 then
if namespace == 0 or testcases then
local eCat = 'AC with '..rct..' elements'
elementsCat = addCat(eCat)
end
end
if parentArgs.state then
if namespace == 0 or testcases then
local sCat
if parentArgs.state == 'collapsed' then sCat = 'AC using state parameter: collapsed'
elseif parentArgs.state == 'expanded' then sCat = 'AC using state parameter: expanded'
elseif parentArgs.state == 'autocollapse' then sCat = 'AC using state parameter: autocollapse'
else sCat = 'AC using state parameter: other'
end
stateCat = addCat(sCat)
end
end
local auxCats = worldcatCat..elementsCat..multipleIdCat..suppressedIdCat..suppressedIdCatArts..
deprecatedIdCat..differentOnWDCat..sameOnWDCat..stateCat
if testcases then
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
end
--out
outString = outString..auxCats
if namespace ~= 0 then
outString = mw.ustring.gsub(outString, '(%[%[)(Category:Articles)', '%1:%2') --by definition
end
return outString
end
return p
cd0db2cc5bc4d9d60808eaacdd367d8aacb169ea
File:Logospaceman.png
6
28
59
2022-07-31T05:52:08Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=Logo of the wiki}}
|date=2022-07-31
|source={{own}}
|author=[[User:SpaceMan|SpaceMan]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
bd00519072e5e85ddc30932d9abf65a3044ae7be
Template:Sky/styles.css
10
166
347
2022-08-01T07:46:16Z
Canopus >Ymblanter
0
Changed protection settings for "[[Template:Sky/styles.css]]": [[WP:High-risk templates|Highly visible template]]: request at [[WP:RFPP]] ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))
text
text/plain
/* {{pp-template}} */
/* Similiar to [[Template:Coord]] styling */
.sky-coordinates-display {
line-height: 1.5em;
text-align: right;
text-indent: 0;
text-transform: none;
white-space: nowrap;
}
body.skin-vector-legacy .sky-coordinates-display {
font-size: 85%;
}
fb0dd75a941049acd566292c9241b00d7088d099
Module:Citation/CS1/Configuration
828
51
117
2022-08-03T21:57:10Z
Canopus >Trappist the monk
0
bump pmid;
Scribunto
text/plain
local lang_obj = mw.language.getContentLanguage(); -- make a language object for the local language; used here for languages and dates
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E S >------------------------------
List of namespaces that should not be included in citation error categories.
Same as setting notracking = true by default.
Note: Namespace names should use underscores instead of spaces.
]]
local uncategorized_namespaces = { 'User', 'Talk', 'User_talk', 'Wikipedia_talk',
'File_talk', 'Template_talk', 'Help_talk', 'Category_talk', 'Portal_talk',
'Book_talk', 'Draft_talk', 'Education_Program_talk', 'Module_talk', 'MediaWiki_talk' };
local uncategorized_subpages = {'/[Ss]andbox', '/[Tt]estcases', '/[^/]*[Ll]og', '/[Aa]rchive'}; -- list of Lua patterns found in page names of pages we should not categorize
--[[--------------------------< M E S S A G E S >--------------------------------------------------------------
Translation table
The following contains fixed text that may be output as part of a citation.
This is separated from the main body to aid in future translations of this
module.
]]
local messages = {
['agency'] = '$1 $2', -- $1 is sepc, $2 is agency
['archived-dead'] = 'Archived from $1 on $2',
['archived-live'] = '$1 from the original on $2',
['archived-missing'] = 'Archived from the original$1 on $2',
['archived-unfit'] = 'Archived from the original on ',
['archived'] = 'Archived',
['by'] = 'By', -- contributions to authored works: introduction, foreword, afterword
['cartography'] = 'Cartography by $1',
['editor'] = 'ed.',
['editors'] = 'eds.',
['edition'] = '($1 ed.)',
['episode'] = 'Episode $1',
['et al'] = 'et al.',
['in'] = 'In', -- edited works
['inactive'] = 'inactive',
['inset'] = '$1 inset',
['interview'] = 'Interviewed by $1',
['lay summary'] = 'Lay summary',
['mismatch'] = '<code class="cs1-code">|$1=</code> / <code class="cs1-code">|$2=</code> mismatch', -- $1 is year param name; $2 is date param name
['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]: $1',
['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none
['original'] = 'the original',
['origdate'] = ' [$1]',
['published'] = ' (published $1)',
['retrieved'] = 'Retrieved $1',
['season'] = 'Season $1',
['section'] = '§ $1',
['sections'] = '§§ $1',
['series'] = '$1 $2', -- $1 is sepc, $2 is series
['seriesnum'] = 'Series $1',
['translated'] = 'Translated by $1',
['type'] = ' ($1)', -- for titletype
['written'] = 'Written at $1',
['vol'] = '$1 Vol. $2', -- $1 is sepc; bold journal style volume is in presentation{}
['vol-no'] = '$1 Vol. $2, no. $3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization)
['issue'] = '$1 No. $2', -- $1 is sepc
['j-vol'] = '$1 $2', -- sepc, volume; bold journal volume is in presentation{}
['j-issue'] = ' ($1)',
['nopp'] = '$1 $2'; -- page(s) without prefix; $1 is sepc
['p-prefix'] = "$1 p. $2", -- $1 is sepc
['pp-prefix'] = "$1 pp. $2", -- $1 is sepc
['j-page(s)'] = ': $1', -- same for page and pages
['sheet'] = '$1 Sheet $2', -- $1 is sepc
['sheets'] = '$1 Sheets $2', -- $1 is sepc
['j-sheet'] = ': Sheet $1',
['j-sheets'] = ': Sheets $1',
['language'] = '(in $1)',
['via'] = " – via $1",
['event'] = 'Event occurs at',
['minutes'] = 'minutes in',
-- Determines the location of the help page
['help page link'] = 'Help:CS1 errors',
['help page label'] = 'help',
-- categories
['cat wikilink'] = '[[Category:$1]]', -- $1 is the category name
[':cat wikilink'] = '[[:Category:$1|link]]', -- category name as maintenance message wikilink; $1 is the category name
-- Internal errors (should only occur if configuration is bad)
['undefined_error'] = 'Called with an undefined error condition',
['unknown_ID_key'] = 'Unrecognized ID key: ', -- an ID key in id_handlers not found in ~/Identifiers func_map{}
['unknown_ID_access'] = 'Unrecognized ID access keyword: ', -- an ID access keyword in id_handlers not found in keywords_lists['id-access']{}
['unknown_argument_map'] = 'Argument map not defined for this variable',
['bare_url_no_origin'] = 'Bare URL found but origin indicator is nil or empty',
['warning_msg_e'] = '<span style="color:#d33">One or more <code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code> templates have errors</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link
['warning_msg_m'] = '<span style="color:#3a3">One or more <code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code> templates have maintenance messages</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link
}
--[[--------------------------< C I T A T I O N _ C L A S S _ M A P >------------------------------------------
this table maps the value assigned to |CitationClass= in the cs1|2 templates to the canonical template name when
the value assigned to |CitationClass= is different from the canonical template name. |CitationClass= values are
used as class attributes in the <cite> tag that encloses the citation so these names may not contain spaces while
the canonical template name may. These names are used in warning_msg_e and warning_msg_m to create links to the
template's documentation when an article is displayed in preivew mode.
Most cs1|2 template |CitationClass= values at en.wiki match their canonical template names so are not listed here.
]]
local citation_class_map_t = { -- TODO: if kept, these and all other config.CitationClass 'names' require some sort of i18n
['audio-visual'] = 'AV media', -- TODO: move to ~/Configuration
['AV-media-notes'] = 'AV media notes',
['encyclopaedia'] = 'encyclopedia',
['mailinglist'] = 'mailing list',
['pressrelease'] = 'press release'
}
--[=[-------------------------< E T _ A L _ P A T T E R N S >--------------------------------------------------
This table provides Lua patterns for the phrase "et al" and variants in name text
(author, editor, etc.). The main module uses these to identify and emit the 'etal' message.
]=]
local et_al_patterns = {
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][%.;,\"']*$", -- variations on the 'et al' theme
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][Ii][AaIi][Ee]?[%.;,\"']*$", -- variations on the 'et alia', 'et alii' and 'et aliae' themes (false positive 'et aliie' unlikely to match)
"[;,]? *%f[%a]and [Oo]thers", -- an alternative to et al.
"%[%[ *[Ee][Tt]%.? *[Aa][Ll]%.? *%]%]", -- a wikilinked form
"%(%( *[Ee][Tt]%.? *[Aa][Ll]%.? *%)%)", -- a double-bracketed form (to counter partial removal of ((...)) syntax)
"[%(%[] *[Ee][Tt]%.? *[Aa][Ll]%.? *[%)%]]", -- a bracketed form
}
--[[--------------------------< P R E S E N T A T I O N >------------------------
Fixed presentation markup. Originally part of citation_config.messages it has
been moved into its own, more semantically correct place.
]]
local presentation =
{
-- .citation-comment class is specified at Help:CS1_errors#Controlling_error_message_display
['hidden-error'] = '<span class="cs1-hidden-error citation-comment">$1</span>',
['visible-error'] = '<span class="cs1-visible-error citation-comment">$1</span>',
['hidden-maint'] = '<span class="cs1-maint citation-comment">$1</span>',
['accessdate'] = '<span class="reference-accessdate">$1$2</span>', -- to allow editors to hide accessdate using personal CSS
['bdi'] = '<bdi$1>$2</bdi>', -- bidirectional isolation used with |script-title= and the like
['cite'] = '<cite class="$1">$2</cite>'; -- for use when citation does not have a namelist and |ref= not set so no id="..." attribute
['cite-id'] = '<cite id="$1" class="$2">$3</cite>'; -- for use when when |ref= is set or when citation has a namelist
['format'] = ' <span class="cs1-format">($1)</span>', -- for |format=, |chapter-format=, etc.
-- various access levels, for |access=, |doi-access=, |arxiv=, ...
-- narrow no-break space   may work better than nowrap CSS. Or not? Browser support?
['ext-link-access-signal'] = '<span class="$1" title="$2">$3</span>', -- external link with appropriate lock icon
['free'] = {class='cs1-lock-free', title='Freely accessible'}, -- classes defined in Module:Citation/CS1/styles.css
['registration'] = {class='cs1-lock-registration', title='Free registration required'},
['limited'] = {class='cs1-lock-limited', title='Free access subject to limited trial, subscription normally required'},
['subscription'] = {class='cs1-lock-subscription', title='Paid subscription required'},
['interwiki-icon'] = '<span class="$1" title="$2">$3</span>',
['class-wikisource'] = 'cs1-ws-icon',
['italic-title'] = "''$1''",
['kern-left'] = '<span class="cs1-kern-left"></span>$1', -- spacing to use when title contains leading single or double quote mark
['kern-right'] = '$1<span class="cs1-kern-right"></span>', -- spacing to use when title contains trailing single or double quote mark
['nowrap1'] = '<span class="nowrap">$1</span>', -- for nowrapping an item: <span ...>yyyy-mm-dd</span>
['nowrap2'] = '<span class="nowrap">$1</span> $2', -- for nowrapping portions of an item: <span ...>dd mmmm</span> yyyy (note white space)
['ocins'] = '<span title="$1" class="Z3988"></span>',
['parameter'] = '<code class="cs1-code">|$1=</code>',
['ps_cs1'] = '.'; -- CS1 style postscript (terminal) character
['ps_cs2'] = ''; -- CS2 style postscript (terminal) character (empty string)
['quoted-text'] = '<q>$1</q>', -- for wrapping |quote= content
['quoted-title'] = '"$1"',
['sep_cs1'] = '.', -- CS1 element separator
['sep_cs2'] = ',', -- CS2 separator
['sep_nl'] = ';', -- CS1|2 style name-list separator between names is a semicolon
['sep_nl_and'] = ' and ', -- used as last nl sep when |name-list-style=and and list has 2 items
['sep_nl_end'] = '; and ', -- used as last nl sep when |name-list-style=and and list has 3+ names
['sep_name'] = ', ', -- CS1|2 style last/first separator is <comma><space>
['sep_nl_vanc'] = ',', -- Vancouver style name-list separator between authors is a comma
['sep_name_vanc'] = ' ', -- Vancouver style last/first separator is a space
['sep_list'] = ', ', -- used for |language= when list has 3+ items except for last sep which uses sep_list_end
['sep_list_pair'] = ' and ', -- used for |language= when list has 2 items
['sep_list_end'] = ', and ', -- used as last list sep for |language= when list has 3+ items
['trans-italic-title'] = "[''$1'']",
['trans-quoted-title'] = "[$1]", -- for |trans-title= and |trans-quote=
['vol-bold'] = '$1 <b>$2</b>', -- sepc, volume; for bold journal cites; for other cites ['vol'] in messages{}
}
--[[--------------------------< A L I A S E S >---------------------------------
Aliases table for commonly passed parameters.
Parameter names on the right side in the assignments in this table must have been
defined in the Whitelist before they will be recognized as valid parameter names
]]
local aliases = {
['AccessDate'] = {'access-date', 'accessdate'}, -- Used by InternetArchiveBot
['Agency'] = 'agency',
['ArchiveDate'] = {'archive-date', 'archivedate'}, -- Used by InternetArchiveBot
['ArchiveFormat'] = 'archive-format',
['ArchiveURL'] = {'archive-url', 'archiveurl'}, -- Used by InternetArchiveBot
['ASINTLD'] = 'asin-tld',
['At'] = 'at', -- Used by InternetArchiveBot
['Authors'] = {'authors', 'people', 'credits'},
['BookTitle'] = {'book-title', 'booktitle'},
['Cartography'] = 'cartography',
['Chapter'] = {'chapter', 'contribution', 'entry', 'article', 'section'},
['ChapterFormat'] = {'chapter-format', 'contribution-format', 'entry-format',
'article-format', 'section-format'};
['ChapterURL'] = {'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url', 'chapterurl'}, -- Used by InternetArchiveBot
['ChapterUrlAccess'] = {'chapter-url-access', 'contribution-url-access',
'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot
['Class'] = 'class', -- cite arxiv and arxiv identifier
['Collaboration'] = 'collaboration',
['Conference'] = {'conference', 'event'},
['ConferenceFormat'] = 'conference-format',
['ConferenceURL'] = 'conference-url', -- Used by InternetArchiveBot
['Date'] = {'date', 'air-date', 'airdate'}, -- air-date and airdate for cite episode and cite serial only
['Degree'] = 'degree',
['DF'] = 'df',
['DisplayAuthors'] = {'display-authors', 'display-subjects'},
['DisplayContributors'] = 'display-contributors',
['DisplayEditors'] = 'display-editors',
['DisplayInterviewers'] = 'display-interviewers',
['DisplayTranslators'] = 'display-translators',
['Docket'] = 'docket',
['DoiBroken'] = 'doi-broken-date',
['Edition'] = 'edition',
['Embargo'] = 'pmc-embargo-date',
['Encyclopedia'] = {'encyclopedia', 'encyclopaedia', 'dictionary'}, -- cite encyclopedia only
['Episode'] = 'episode', -- cite serial only TODO: make available to cite episode?
['Format'] = 'format',
['ID'] = {'id', 'ID'},
['Inset'] = 'inset',
['Issue'] = {'issue', 'number'},
['Language'] = {'language', 'lang'},
['LayDate'] = 'lay-date',
['LayFormat'] = 'lay-format',
['LaySource'] = 'lay-source',
['LayURL'] = 'lay-url',
['MailingList'] = {'mailing-list', 'mailinglist'}, -- cite mailing list only
['Map'] = 'map', -- cite map only
['MapFormat'] = 'map-format', -- cite map only
['MapURL'] = {'map-url', 'mapurl'}, -- cite map only -- Used by InternetArchiveBot
['MapUrlAccess'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot
['Minutes'] = 'minutes',
['Mode'] = 'mode',
['NameListStyle'] = 'name-list-style',
['Network'] = 'network',
['Newsgroup'] = 'newsgroup', -- cite newsgroup only
['NoPP'] = {'no-pp', 'nopp'},
['NoTracking'] = {'no-tracking', 'template-doc-demo'},
['Number'] = 'number', -- this case only for cite techreport
['OrigDate'] = {'orig-date', 'orig-year', 'origyear'},
['Others'] = 'others',
['Page'] = {'page', 'p'}, -- Used by InternetArchiveBot
['Pages'] = {'pages', 'pp'}, -- Used by InternetArchiveBot
['Periodical'] = {'journal', 'magazine', 'newspaper', 'periodical', 'website', 'work'},
['Place'] = {'place', 'location'},
['PostScript'] = 'postscript',
['PublicationDate'] = {'publication-date', 'publicationdate'},
['PublicationPlace'] = {'publication-place', 'publicationplace'},
['PublisherName'] = {'publisher', 'institution'},
['Quote'] = {'quote', 'quotation'},
['QuotePage'] = 'quote-page',
['QuotePages'] = 'quote-pages',
['Ref'] = 'ref',
['Scale'] = 'scale',
['ScriptChapter'] = {'script-chapter', 'script-contribution', 'script-entry',
'script-article', 'script-section'},
['ScriptMap'] = 'script-map',
['ScriptPeriodical'] = {'script-journal', 'script-magazine', 'script-newspaper',
'script-periodical', 'script-website', 'script-work'},
['ScriptQuote'] = 'script-quote',
['ScriptTitle'] = 'script-title', -- Used by InternetArchiveBot
['Season'] = 'season',
['Sections'] = 'sections', -- cite map only
['Series'] = {'series', 'version'},
['SeriesLink'] = {'series-link', 'serieslink'},
['SeriesNumber'] = {'series-number', 'series-no'},
['Sheet'] = 'sheet', -- cite map only
['Sheets'] = 'sheets', -- cite map only
['Station'] = 'station',
['Time'] = 'time',
['TimeCaption'] = 'time-caption',
['Title'] = 'title', -- Used by InternetArchiveBot
['TitleLink'] = {'title-link', 'episode-link', 'episodelink'}, -- Used by InternetArchiveBot
['TitleNote'] = 'department',
['TitleType'] = {'type', 'medium'},
['TransChapter'] = {'trans-article', 'trans-chapter', 'trans-contribution',
'trans-entry', 'trans-section'},
['Transcript'] = 'transcript',
['TranscriptFormat'] = 'transcript-format',
['TranscriptURL'] = {'transcript-url', 'transcripturl'}, -- Used by InternetArchiveBot
['TransMap'] = 'trans-map', -- cite map only
['TransPeriodical'] = {'trans-journal', 'trans-magazine', 'trans-newspaper',
'trans-periodical', 'trans-website', 'trans-work'},
['TransQuote'] = 'trans-quote',
['TransTitle'] = 'trans-title', -- Used by InternetArchiveBot
['URL'] = {'url', 'URL'}, -- Used by InternetArchiveBot
['UrlAccess'] = 'url-access', -- Used by InternetArchiveBot
['UrlStatus'] = 'url-status', -- Used by InternetArchiveBot
['Vauthors'] = 'vauthors',
['Veditors'] = 'veditors',
['Via'] = 'via',
['Volume'] = 'volume',
['Year'] = 'year',
['AuthorList-First'] = {"first#", "author-first#", "author#-first", "given#",
"author-given#", "author#-given"},
['AuthorList-Last'] = {"last#", "author-last#", "author#-last", "surname#",
"author-surname#", "author#-surname", "author#", "subject#", 'host#'},
['AuthorList-Link'] = {"author-link#", "author#-link", "subject-link#",
"subject#-link", "authorlink#", "author#link"},
['AuthorList-Mask'] = {"author-mask#", "author#-mask", "subject-mask#", "subject#-mask"},
['ContributorList-First'] = {'contributor-first#', 'contributor#-first',
'contributor-given#', 'contributor#-given'},
['ContributorList-Last'] = {'contributor-last#', 'contributor#-last',
'contributor-surname#', 'contributor#-surname', 'contributor#'},
['ContributorList-Link'] = {'contributor-link#', 'contributor#-link'},
['ContributorList-Mask'] = {'contributor-mask#', 'contributor#-mask'},
['EditorList-First'] = {"editor-first#", "editor#-first", "editor-given#", "editor#-given"},
['EditorList-Last'] = {"editor-last#", "editor#-last", "editor-surname#",
"editor#-surname", "editor#"},
['EditorList-Link'] = {"editor-link#", "editor#-link"},
['EditorList-Mask'] = {"editor-mask#", "editor#-mask"},
['InterviewerList-First'] = {'interviewer-first#', 'interviewer#-first',
'interviewer-given#', 'interviewer#-given'},
['InterviewerList-Last'] = {'interviewer-last#', 'interviewer#-last',
'interviewer-surname#', 'interviewer#-surname', 'interviewer#'},
['InterviewerList-Link'] = {'interviewer-link#', 'interviewer#-link'},
['InterviewerList-Mask'] = {'interviewer-mask#', 'interviewer#-mask'},
['TranslatorList-First'] = {'translator-first#', 'translator#-first',
'translator-given#', 'translator#-given'},
['TranslatorList-Last'] = {'translator-last#', 'translator#-last',
'translator-surname#', 'translator#-surname', 'translator#'},
['TranslatorList-Link'] = {'translator-link#', 'translator#-link'},
['TranslatorList-Mask'] = {'translator-mask#', 'translator#-mask'},
}
--[[--------------------------< P U N C T _ S K I P >---------------------------
builds a table of parameter names that the extraneous terminal punctuation check should not check.
]]
local punct_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'BookTitle', 'Chapter', 'ScriptChapter', 'ScriptTitle', 'Title', 'TransChapter', 'Transcript', 'TransMap', 'TransTitle', -- title-holding parameters
'AuthorList-Mask', 'ContributorList-Mask', 'EditorList-Mask', 'InterviewerList-Mask', 'TranslatorList-Mask', -- name-list mask may have name separators
'PostScript', 'Quote', 'ScriptQuote', 'TransQuote', 'Ref', -- miscellaneous
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'LayURL', 'MapURL', 'TranscriptURL', 'URL', -- URL-holding parameters
}
local url_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'ID', 'LayURL', 'MapURL', 'TranscriptURL', 'URL', -- parameters allowed to hold urls
'Page', 'Pages', 'At', 'QuotePage', 'QuotePages', -- insource locators allowed to hold urls
}
local function build_skip_table (skip_t, meta_params)
for _, meta_param in ipairs (meta_params) do -- for each meta parameter key
local params = aliases[meta_param]; -- get the parameter or the table of parameters associated with the meta parameter name
if 'string' == type (params) then
skip_t[params] = 1; -- just a single parameter
else
for _, param in ipairs (params) do -- get the parameter name
skip_t[param] = 1; -- add the parameter name to the skip table
local count;
param, count = param:gsub ('#', ''); -- remove enumerator marker from enumerated parameters
if 0 ~= count then -- if removed
skip_t[param] = 1; -- add param name without enumerator marker
end
end
end
end
return skip_t;
end
local punct_skip = {};
local url_skip = {};
--[[-----------< S P E C I A L C A S E T R A N S L A T I O N S >------------
This table is primarily here to support internationalization. Translations in
this table are used, for example, when an error message, category name, etc.,
is extracted from the English alias key. There may be other cases where
this translation table may be useful.
]]
local is_Latn = 'A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143';
local special_case_translation = {
['AuthorList'] = 'authors list', -- used to assemble maintenance category names
['ContributorList'] = 'contributors list', -- translation of these names plus translation of the base mainenance category names in maint_cats{} table below
['EditorList'] = 'editors list', -- must match the names of the actual categories
['InterviewerList'] = 'interviewers list', -- this group or translations used by name_has_ed_markup() and name_has_mult_names()
['TranslatorList'] = 'translators list',
-- Lua patterns to match pseudo-titles used by InternetArchiveBot and others as placeholder for unknown |title= value
['archived_copy'] = { -- used with CS1 maint: Archive[d] copy as title
['en'] = '^archived?%s+copy$', -- for English; translators: keep this because templates imported from en.wiki
['local'] = nil, -- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
},
-- Lua patterns to match generic titles; usually created by bots or reference filling tools
-- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
-- generic titles and patterns in this table should be lowercase only
-- leave ['local'] nil except when there is a matching generic title in your language
-- boolean 'true' for plain-text searches; 'false' for pattern searches
['generic_titles'] = {
['accept'] = {
},
['reject'] = {
{['en'] = {'^wayback%s+machine$', false}, ['local'] = nil},
{['en'] = {'are you a robot', true}, ['local'] = nil},
{['en'] = {'hugedomains.com', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?no +title[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'page not found', true}, ['local'] = nil},
{['en'] = {'subscribe to read', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?unknown[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'website is for sale', true}, ['local'] = nil},
{['en'] = {'^404', false}, ['local'] = nil},
{['en'] = {'internet archive wayback machine', true}, ['local'] = nil},
{['en'] = {'log into facebook', true}, ['local'] = nil},
{['en'] = {'login • instagram', true}, ['local'] = nil},
{['en'] = {'redirecting...', true}, ['local'] = nil},
{['en'] = {'usurped title', true}, ['local'] = nil}, -- added by a GreenC bot
{['en'] = {'webcite query result', true}, ['local'] = nil},
{['en'] = {'wikiwix\'s cache', true}, ['local'] = nil},
}
},
-- boolean 'true' for plain-text searches, search string must be lowercase only
-- boolean 'false' for pattern searches
-- leave ['local'] nil except when there is a matching generic name in your language
['generic_names'] = {
['accept'] = {
{['en'] = {'%[%[[^|]*%(author%) *|[^%]]*%]%]', false}, ['local'] = nil},
},
['reject'] = {
{['en'] = {'about us', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]dvisor%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]uthor%f[%A]', false}, ['local'] = nil},
{['en'] = {'collaborator', true}, ['local'] = nil},
{['en'] = {'contributor', true}, ['local'] = nil},
{['en'] = {'contact us', true}, ['local'] = nil},
{['en'] = {'directory', true}, ['local'] = nil},
{['en'] = {'%f[%(%[][%(%[]%s*eds?%.?%s*[%)%]]?$', false}, ['local'] = nil},
{['en'] = {'[,%.%s]%f[e]eds?%.?$', false}, ['local'] = nil},
{['en'] = {'^eds?[%.,;]', false}, ['local'] = nil},
{['en'] = {'^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]dited%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]ditors?%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a]]Ee]mail%f[%A]', false}, ['local'] = nil},
{['en'] = {'facebook', true}, ['local'] = nil},
{['en'] = {'google', true}, ['local'] = nil},
{['en'] = {'home page', true}, ['local'] = nil},
{['en'] = {'instagram', true}, ['local'] = nil},
{['en'] = {'interviewer', true}, ['local'] = nil},
{['en'] = {'linkedIn', true}, ['local'] = nil},
{['en'] = {'^[Nn]ews$', false}, ['local'] = nil},
{['en'] = {'pinterest', true}, ['local'] = nil},
{['en'] = {'policy', true}, ['local'] = nil},
{['en'] = {'privacy', true}, ['local'] = nil},
{['en'] = {'translator', true}, ['local'] = nil},
{['en'] = {'tumblr', true}, ['local'] = nil},
{['en'] = {'twitter', true}, ['local'] = nil},
{['en'] = {'site name', true}, ['local'] = nil},
{['en'] = {'statement', true}, ['local'] = nil},
{['en'] = {'submitted', true}, ['local'] = nil},
{['en'] = {'super.?user', false}, ['local'] = nil},
{['en'] = {'%f['..is_Latn..'][Uu]ser%f[^'..is_Latn..']', false}, ['local'] = nil},
{['en'] = {'verfasser', true}, ['local'] = nil},
}
}
}
--[[--------------------------< D A T E _ N A M E S >----------------------------------------------------------
This table of tables lists local language date names and fallback English date names.
The code in Date_validation will look first in the local table for valid date names.
If date names are not found in the local table, the code will look in the English table.
Because citations can be copied to the local wiki from en.wiki, the English is
required when the date-name translation function date_name_xlate() is used.
In these tables, season numbering is defined by
Extended Date/Time Format (EDTF) Specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard
defines various divisions using numbers 21-41. CS1|2 only supports generic seasons.
EDTF does support the distinction between north and south hemisphere seasons
but CS1|2 has no way to make that distinction.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
The standard does not address 'named' dates so, for the purposes of CS1|2,
Easter and Christmas are defined here as 98 and 99, which should be out of the
ISO 8601 (EDTF) range of uses for a while.
local_date_names_from_mediawiki is a boolean. When set to:
true – module will fetch local month names from MediaWiki for both date_names['local']['long'] and date_names['local']['short']
false – module will *not* fetch local month names from MediaWiki
Caveat lector: There is no guarantee that MediaWiki will provide short month names. At your wiki you can test
the results of the MediaWiki fetch in the debug console with this command (the result is alpha sorted):
=mw.dumpObject (p.date_names['local'])
While the module can fetch month names from MediaWiki, it cannot fetch the quarter, season, and named date names
from MediaWiki. Those must be translated manually.
]]
local local_date_names_from_mediawiki = true; -- when false, manual translation required for date_names['local']['long'] and date_names['local']['short']
-- when true, module fetches long and short month names from MediaWiki
local date_names = {
['en'] = { -- English
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
-- when local_date_names_from_mediawiki = false
['local'] = { -- replace these English date names with the local language equivalents
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
['inv_local_long'] = {}, -- used in date reformatting & translation; copy of date_names['local'].long where k/v are inverted: [1]='<local name>' etc.
['inv_local_short'] = {}, -- used in date reformatting & translation; copy of date_names['local'].short where k/v are inverted: [1]='<local name>' etc.
['inv_local_quarter'] = {}, -- used in date translation; copy of date_names['local'].quarter where k/v are inverted: [1]='<local name>' etc.
['inv_local_season'] = {}, -- used in date translation; copy of date_names['local'].season where k/v are inverted: [1]='<local name>' etc.
['inv_local_named'] = {}, -- used in date translation; copy of date_names['local'].named where k/v are inverted: [1]='<local name>' etc.
['local_digits'] = {['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4', ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9'}, -- used to convert local language digits to Western 0-9
['xlate_digits'] = {},
}
if local_date_names_from_mediawiki then -- if fetching local month names from MediaWiki is enabled
local long_t = {};
local short_t = {};
for i=1, 12 do -- loop 12x and
local name = lang_obj:formatDate('F', '2022-' .. i .. '-1'); -- get long month name for each i
long_t[name] = i; -- save it
name = lang_obj:formatDate('M', '2022-' .. i .. '-1'); -- get short month name for each i
short_t[name] = i; -- save it
end
date_names['local']['long'] = long_t; -- write the long table – overwrites manual translation
date_names['local']['short'] = short_t; -- write the short table – overwrites manual translation
end
-- create inverted date-name tables for reformatting and/or translation
for _, invert_t in pairs {{'long', 'inv_local_long'}, {'short', 'inv_local_short'}, {'quarter', 'inv_local_quarter'}, {'season', 'inv_local_season'}, {'named', 'inv_local_named'}} do
for name, i in pairs (date_names['local'][invert_t[1]]) do -- this table is ['name'] = i
date_names[invert_t[2]][i] = name; -- invert to get [i] = 'name' for conversions from ymd
end
end
for ld, ed in pairs (date_names.local_digits) do -- make a digit translation table for simple date translation from en to local language using local_digits table
date_names.xlate_digits [ed] = ld; -- en digit becomes index with local digit as the value
end
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}}
'{{ *[Uu]se +(dmy) +dates *[|}]', -- 1159k -- sorted by approximate transclusion count
'{{ *[Uu]se +(mdy) +dates *[|}]', -- 212k
'{{ *[Uu]se +(MDY) +dates *[|}]', -- 788
'{{ *[Uu]se +(DMY) +dates *[|}]', -- 343
'{{ *([Mm]dy) *[|}]', -- 176
'{{ *[Uu]se *(dmy) *[|}]', -- 156 + 18
'{{ *[Uu]se *(mdy) *[|}]', -- 149 + 11
'{{ *([Dd]my) *[|}]', -- 56
'{{ *[Uu]se +(MDY) *[|}]', -- 5
'{{ *([Dd]MY) *[|}]', -- 3
'{{ *[Uu]se(mdy)dates *[|}]', -- 1
'{{ *[Uu]se +(DMY) *[|}]', -- 0
'{{ *([Mm]DY) *[|}]', -- 0
}
local function get_date_format ()
local title_object = mw.title.getCurrentTitle();
if title_object.namespace == 10 then -- not in template space so that unused templates appear in unused-template-reports;
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
local content = title_object:getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects
local start, _, match = content:find(pattern); -- match is the three letters indicating desired date format
if match then
content = content:match ('%b{}', start); -- get the whole template
if content:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length
return match:lower() .. '-' .. content:match ('| *cs1%-dates *= *([lsy][sy]?)');
else
return match:lower() .. '-all'; -- no |cs1-dates= k/v pair; return value appropriate for use in |df=
end
end
end
end
local global_df;
--[[-----------------< V O L U M E , I S S U E , P A G E S >------------------
These tables hold cite class values (from the template invocation) and identify those templates that support
|volume=, |issue=, and |page(s)= parameters. Cite conference and cite map require further qualification which
is handled in the main module.
]]
local templates_using_volume = {'citation', 'audio-visual', 'book', 'conference', 'encyclopaedia', 'interview', 'journal', 'magazine', 'map', 'news', 'report', 'techreport', 'thesis'}
local templates_using_issue = {'citation', 'conference', 'episode', 'interview', 'journal', 'magazine', 'map', 'news', 'podcast'}
local templates_not_using_page = {'audio-visual', 'episode', 'mailinglist', 'newsgroup', 'podcast', 'serial', 'sign', 'speech'}
--[[
These tables control when it is appropriate for {{citation}} to render |volume= and/or |issue=. The parameter
names in the tables constrain {{citation}} so that its renderings match the renderings of the equivalent cs1
templates. For example, {{cite web}} does not support |volume= so the equivalent {{citation |website=...}} must
not support |volume=.
]]
local citation_no_volume_t = { -- {{citation}} does not render |volume= when these parameters are used
'website', 'mailinglist', 'script-website',
}
local citation_issue_t = { -- {{citation}} may render |issue= when these parameters are used
'journal', 'magazine', 'newspaper', 'periodical', 'work',
'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-work',
}
--[[
Patterns for finding extra text in |volume=, |issue=, |page=, |pages=
]]
local vol_iss_pg_patterns = {
good_ppattern = '^P[^%.PpGg]', -- OK to begin with uppercase P: P7 (page 7 of section P), but not p123 (page 123); TODO: this allows 'Pages' which it should not
bad_ppatterns = { -- patterns for |page= and |pages=
'^[Pp][PpGg]?%.?[ %d]',
'^[Pp][Pp]?%. ', -- from {{p.}} and {{pp.}} templates
'^[Pp]ages?',
'^[Pp]gs.?',
},
vpatterns = { -- patterns for |volume=
'^volumes?',
'^vols?[%.:=]?'
},
ipatterns = { -- patterns for |issue=
'^issues?',
'^iss[%.:=]?',
'^numbers?',
'^nos?%A', -- don't match 'november' or 'nostradamus'
'^nr[%.:=]?',
'^n[%.:= ]' -- might be a valid issue without separator (space char is sep char here)
}
}
--[[--------------------------< K E Y W O R D S >-------------------------------
These tables hold keywords for those parameters that have defined sets of acceptable keywords.
]]
--[[-------------------< K E Y W O R D S T A B L E >--------------------------
this is a list of keywords; each key in the list is associated with a table of
synonymous keywords possibly from different languages.
for I18N: add local-language keywords to value table; do not change the key.
For example, adding the German keyword 'ja':
['affirmative'] = {'yes', 'true', 'y', 'ja'},
Because CS1|2 templates from en.wiki articles are often copied to other local wikis,
it is recommended that the English keywords remain in these tables.
]]
local keywords = {
['amp'] = {'&', 'amp', 'ampersand'}, -- |name-list-style=
['and'] = {'and', 'serial'}, -- |name-list-style=
['affirmative'] = {'yes', 'true', 'y'}, -- |no-tracking=, |no-pp= -- Used by InternetArchiveBot
['afterword'] = {'afterword'}, -- |contribution=
['bot: unknown'] = {'bot: unknown'}, -- |url-status= -- Used by InternetArchiveBot
['cs1'] = {'cs1'}, -- |mode=
['cs2'] = {'cs2'}, -- |mode=
['dead'] = {'dead', 'deviated'}, -- |url-status= -- Used by InternetArchiveBot
['dmy'] = {'dmy'}, -- |df=
['dmy-all'] = {'dmy-all'}, -- |df=
['foreword'] = {'foreword'}, -- |contribution=
['free'] = {'free'}, -- |<id>-access= -- Used by InternetArchiveBot
['harv'] = {'harv'}, -- |ref=; this no longer supported; is_valid_parameter_value() called with <invert> = true
['introduction'] = {'introduction'}, -- |contribution=
['limited'] = {'limited'}, -- |url-access= -- Used by InternetArchiveBot
['live'] = {'live'}, -- |url-status= -- Used by InternetArchiveBot
['mdy'] = {'mdy'}, -- |df=
['mdy-all'] = {'mdy-all'}, -- |df=
['none'] = {'none'}, -- |postscript=, |ref=, |title=, |type= -- Used by InternetArchiveBot
['off'] = {'off'}, -- |title= (potentially also: |title-link=, |postscript=, |ref=, |type=)
['preface'] = {'preface'}, -- |contribution=
['registration'] = {'registration'}, -- |url-access= -- Used by InternetArchiveBot
['subscription'] = {'subscription'}, -- |url-access= -- Used by InternetArchiveBot
['unfit'] = {'unfit'}, -- |url-status= -- Used by InternetArchiveBot
['usurped'] = {'usurped'}, -- |url-status= -- Used by InternetArchiveBot
['vanc'] = {'vanc'}, -- |name-list-style=
['ymd'] = {'ymd'}, -- |df=
['ymd-all'] = {'ymd-all'}, -- |df=
-- ['yMd'] = {'yMd'}, -- |df=; not supported at en.wiki
-- ['yMd-all'] = {'yMd-all'}, -- |df=; not supported at en.wiki
}
--[[------------------------< X L A T E _ K E Y W O R D S >---------------------
this function builds a list, keywords_xlate{}, of the keywords found in keywords{} where the values from keywords{}
become the keys in keywords_xlate{} and the keys from keywords{} become the values in keywords_xlate{}:
['affirmative'] = {'yes', 'true', 'y'}, -- in keywords{}
becomes
['yes'] = 'affirmative', -- in keywords_xlate{}
['true'] = 'affirmative',
['y'] = 'affirmative',
the purpose of this function is to act as a translator between a non-English keyword and its English equivalent
that may be used in other modules of this suite
]]
local function xlate_keywords ()
local out_table = {}; -- output goes here
for k, keywords_t in pairs (keywords) do -- spin through the keywords table
for _, keyword in ipairs (keywords_t) do -- for each keyword
out_table[keyword] = k; -- create an entry in the output table where keyword is the key
end
end
return out_table;
end
local keywords_xlate = xlate_keywords (); -- the list of translated keywords
--[[----------------< M A K E _ K E Y W O R D S _ L I S T >---------------------
this function assembles, for parameter-value validation, the list of keywords appropriate to that parameter.
keywords_lists{}, is a table of tables from keywords{}
]]
local function make_keywords_list (keywords_lists)
local out_table = {}; -- output goes here
for _, keyword_list in ipairs (keywords_lists) do -- spin through keywords_lists{} and get a table of keywords
for _, keyword in ipairs (keyword_list) do -- spin through keyword_list{} and add each keyword, ...
table.insert (out_table, keyword); -- ... as plain text, to the output list
end
end
return out_table;
end
--[[----------------< K E Y W O R D S _ L I S T S >-----------------------------
this is a list of lists of valid keywords for the various parameters in [key].
Generally the keys in this table are the canonical en.wiki parameter names though
some are contrived because of use in multiple differently named parameters:
['yes_true_y'], ['id-access'].
The function make_keywords_list() extracts the individual keywords from the
appropriate list in keywords{}.
The lists in this table are used to validate the keyword assignment for the
parameters named in this table's keys.
]]
local keywords_lists = {
['yes_true_y'] = make_keywords_list ({keywords.affirmative}),
['contribution'] = make_keywords_list ({keywords.afterword, keywords.foreword, keywords.introduction, keywords.preface}),
['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all']}),
-- ['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all'], keywords.yMd, keywords['yMd-all']}), -- not supported at en.wiki
['mode'] = make_keywords_list ({keywords.cs1, keywords.cs2}),
['name-list-style'] = make_keywords_list ({keywords.amp, keywords['and'], keywords.vanc}),
['ref'] = make_keywords_list ({keywords.harv}), -- inverted check; |ref=harv no longer supported
['url-access'] = make_keywords_list ({keywords.subscription, keywords.limited, keywords.registration}),
['url-status'] = make_keywords_list ({keywords.dead, keywords.live, keywords.unfit, keywords.usurped, keywords['bot: unknown']}),
['id-access'] = make_keywords_list ({keywords.free}),
}
--[[---------------------< S T R I P M A R K E R S >----------------------------
Common pattern definition location for stripmarkers so that we don't have to go
hunting for them if (when) MediaWiki changes their form.
]]
local stripmarkers = {
['any'] = '\127[^\127]*UNIQ%-%-(%a+)%-[%a%d]+%-QINU[^\127]*\127', -- capture returns name of stripmarker
['math'] = '\127[^\127]*UNIQ%-%-math%-[%a%d]+%-QINU[^\127]*\127' -- math stripmarkers used in coins_cleanup() and coins_replace_math_stripmarker()
}
--[[------------< I N V I S I B L E _ C H A R A C T E R S >---------------------
This table holds non-printing or invisible characters indexed either by name or
by Unicode group. Values are decimal representations of UTF-8 codes. The table
is organized as a table of tables because the Lua pairs keyword returns table
data in an arbitrary order. Here, we want to process the table from top to bottom
because the entries at the top of the table are also found in the ranges specified
by the entries at the bottom of the table.
Also here is a pattern that recognizes stripmarkers that begin and end with the
delete characters. The nowiki stripmarker is not an error but some others are
because the parameter values that include them become part of the template's
metadata before stripmarker replacement.
]]
local invisible_defs = {
del = '\127', -- used to distinguish between stripmarker and del char
zwj = '\226\128\141', -- used with capture because zwj may be allowed
}
local invisible_chars = {
{'replacement', '\239\191\189'}, -- U+FFFD, EF BF BD
{'zero width joiner', '('.. invisible_defs.zwj .. ')'}, -- U+200D, E2 80 8D; capture because zwj may be allowed
{'zero width space', '\226\128\139'}, -- U+200B, E2 80 8B
{'hair space', '\226\128\138'}, -- U+200A, E2 80 8A
{'soft hyphen', '\194\173'}, -- U+00AD, C2 AD
{'horizontal tab', '\009'}, -- U+0009 (HT), 09
{'line feed', '\010'}, -- U+000A (LF), 0A
{'no-break space', '\194\160'}, -- U+00A0 (NBSP), C2 A0
{'carriage return', '\013'}, -- U+000D (CR), 0D
{'stripmarker', stripmarkers.any}, -- stripmarker; may or may not be an error; capture returns the stripmaker type
{'delete', '('.. invisible_defs.del .. ')'}, -- U+007F (DEL), 7F; must be done after stripmarker test; capture to distinguish isolated del chars not part of stripmarker
{'C0 control', '[\000-\008\011\012\014-\031]'}, -- U+0000–U+001F (NULL–US), 00–1F (except HT, LF, CR (09, 0A, 0D))
{'C1 control', '[\194\128-\194\159]'}, -- U+0080–U+009F (XXX–APC), C2 80 – C2 9F
-- {'Specials', '[\239\191\185-\239\191\191]'}, -- U+FFF9-U+FFFF, EF BF B9 – EF BF BF
-- {'Private use area', '[\238\128\128-\239\163\191]'}, -- U+E000–U+F8FF, EE 80 80 – EF A3 BF
-- {'Supplementary Private Use Area-A', '[\243\176\128\128-\243\191\191\189]'}, -- U+F0000–U+FFFFD, F3 B0 80 80 – F3 BF BF BD
-- {'Supplementary Private Use Area-B', '[\244\128\128\128-\244\143\191\189]'}, -- U+100000–U+10FFFD, F4 80 80 80 – F4 8F BF BD
}
--[[
Indic script makes use of zero width joiner as a character modifier so zwj
characters must be left in. This pattern covers all of the unicode characters
for these languages:
Devanagari 0900–097F – https://unicode.org/charts/PDF/U0900.pdf
Devanagari extended A8E0–A8FF – https://unicode.org/charts/PDF/UA8E0.pdf
Bengali 0980–09FF – https://unicode.org/charts/PDF/U0980.pdf
Gurmukhi 0A00–0A7F – https://unicode.org/charts/PDF/U0A00.pdf
Gujarati 0A80–0AFF – https://unicode.org/charts/PDF/U0A80.pdf
Oriya 0B00–0B7F – https://unicode.org/charts/PDF/U0B00.pdf
Tamil 0B80–0BFF – https://unicode.org/charts/PDF/U0B80.pdf
Telugu 0C00–0C7F – https://unicode.org/charts/PDF/U0C00.pdf
Kannada 0C80–0CFF – https://unicode.org/charts/PDF/U0C80.pdf
Malayalam 0D00–0D7F – https://unicode.org/charts/PDF/U0D00.pdf
plus the not-necessarily Indic scripts for Sinhala and Burmese:
Sinhala 0D80-0DFF - https://unicode.org/charts/PDF/U0D80.pdf
Myanmar 1000-109F - https://unicode.org/charts/PDF/U1000.pdf
Myanmar extended A AA60-AA7F - https://unicode.org/charts/PDF/UAA60.pdf
Myanmar extended B A9E0-A9FF - https://unicode.org/charts/PDF/UA9E0.pdf
the pattern is used by has_invisible_chars() and coins_cleanup()
]]
local indic_script = '[\224\164\128-\224\181\191\224\163\160-\224\183\191\225\128\128-\225\130\159\234\167\160-\234\167\191\234\169\160-\234\169\191]';
-- list of emoji that use zwj character (U+200D) to combine with another emoji
local emoji = { -- indexes are decimal forms of the hex values in U+xxxx
[127752] = true, -- U+1F308 🌈 rainbow
[127806] = true, -- U+1F33E 🌾 ear of rice
[127859] = true, -- U+1F373 🍳 cooking
[127891] = true, -- U+1F393 🎓 graduation cap
[127908] = true, -- U+1F3A4 🎤 microphone
[127912] = true, -- U+1F3A8 🎨 artist palette
[127979] = true, -- U+1F3EB 🏫 school
[127981] = true, -- U+1F3ED 🏭 factory
[128102] = true, -- U+1F466 👦 boy
[128103] = true, -- U+1F467 👧 girl
[128104] = true, -- U+1F468 👨 man
[128105] = true, -- U+1F469 👩 woman
[128139] = true, -- U+1F48B 💋 kiss mark
[128187] = true, -- U+1F4BB 💻 personal computer
[128188] = true, -- U+1F4BC 💼 brief case
[128295] = true, -- U+1F527 🔧 wrench
[128300] = true, -- U+1F52C 🔬 microscope
[128488] = true, -- U+1F5E8 🗨 left speech bubble
[128640] = true, -- U+1F680 🚀 rocket
[128658] = true, -- U+1F692 🚒 fire engine
[129309] = true, -- U+1F91D 🤝 handshake
[129455] = true, -- U+1F9AF 🦯 probing cane
[129456] = true, -- U+1F9B0 🦰 emoji component red hair
[129457] = true, -- U+1F9B1 🦱 emoji component curly hair
[129458] = true, -- U+1F9B2 🦲 emoji component bald
[129459] = true, -- U+1F9B3 🦳 emoji component white hair
[129466] = true, -- U+1F9BA 🦺 safety vest
[129468] = true, -- U+1F9BC 🦼 motorized wheelchair
[129469] = true, -- U+1F9BD 🦽 manual wheelchair
[129489] = true, -- U+1F9D1 🧑 adult
[9760] = true, -- U+2620 ☠ skull and crossbones
[9792] = true, -- U+2640 ♀ female sign
[9794] = true, -- U+2642 ♂ male sign
[9877] = true, -- U+2695 ⚕ staff of aesculapius
[9878] = true, -- U+2696 ⚖ scales
[9992] = true, -- U+2708 ✈ airplane
[10084] = true, -- U+2764 ❤ heavy black heart
}
--[[----------------------< L A N G U A G E S U P P O R T >-------------------
These tables and constants support various language-specific functionality.
]]
--local this_wiki_code = mw.getContentLanguage():getCode(); -- get this wiki's language code
local this_wiki_code = lang_obj:getCode(); -- get this wiki's language code
if string.match (mw.site.server, 'wikidata') then
this_wiki_code = mw.getCurrentFrame():preprocess('{{int:lang}}'); -- on Wikidata so use interface language setting instead
end
local mw_languages_by_tag_t = mw.language.fetchLanguageNames (this_wiki_code, 'all'); -- get a table of language tag/name pairs known to Wikimedia; used for interwiki tests
local mw_languages_by_name_t = {};
for k, v in pairs (mw_languages_by_tag_t) do -- build a 'reversed' table name/tag language pairs know to MediaWiki; used for |language=
v = mw.ustring.lower (v); -- lowercase for tag fetch; get name's proper case from mw_languages_by_tag_t[<tag>]
if mw_languages_by_name_t[v] then -- when name already in the table
if 2 == #k or 3 == #k then -- if tag does not have subtags
mw_languages_by_name_t[v] = k; -- prefer the shortest tag for this name
end
else -- here when name not in the table
mw_languages_by_name_t[v] = k; -- so add name and matching tag
end
end
local inter_wiki_map = {}; -- map of interwiki prefixes that are language-code prefixes
for k, v in pairs (mw.site.interwikiMap ('local')) do -- spin through the base interwiki map (limited to local)
if mw_languages_by_tag_t[v["prefix"]] then -- if the prefix matches a known language tag
inter_wiki_map[v["prefix"]] = true; -- add it to our local map
end
end
--[[--------------------< S C R I P T _ L A N G _ C O D E S >-------------------
This table is used to hold ISO 639-1 two-character and ISO 639-3 three-character
language codes that apply only to |script-title= and |script-chapter=
]]
local script_lang_codes = {
'ab', 'am', 'ar', 'be', 'bg', 'bn', 'bo', 'bs', 'dv', 'dz', 'el', 'fa', 'gu',
'he', 'hi', 'hy', 'ja', 'ka', 'kk', 'km', 'kn', 'ko', 'ku', 'ky', 'lo', 'mk',
'ml', 'mn', 'mr', 'my', 'ne', 'or', 'ota', 'ps', 'ru', 'sd', 'si', 'sr', 'syc',
'ta', 'te', 'tg', 'th', 'ti', 'ug', 'uk', 'ur', 'uz', 'yi', 'yue', 'zh'
};
--[[---------------< L A N G U A G E R E M A P P I N G >----------------------
These tables hold language information that is different (correct) from MediaWiki's definitions
For each ['code'] = 'language name' in lang_code_remap{} there must be a matching ['language name'] = {'language name', 'code'} in lang_name_remap{}
lang_code_remap{}:
key is always lowercase ISO 639-1, -2, -3 language code or a valid lowercase IETF language tag
value is properly spelled and capitalized language name associated with key
only one language name per key;
key/value pair must have matching entry in lang_name_remap{}
lang_name_remap{}:
key is always lowercase language name
value is a table the holds correctly spelled and capitalized language name [1] and associated code [2] (code must match a code key in lang_code_remap{})
may have multiple keys referring to a common preferred name and code; For example:
['kolsch'] and ['kölsch'] both refer to 'Kölsch' and 'ksh'
]]
local lang_code_remap = { -- used for |language= and |script-title= / |script-chapter=
['als'] = 'Tosk Albanian', -- MediaWiki returns Alemannisch
['bh'] = 'Bihari', -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bla'] = 'Blackfoot', -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['bn'] = 'Bengali', -- MediaWiki returns Bangla
['ca-valencia'] = 'Valencian', -- IETF variant of Catalan
['ilo'] = 'Ilocano', -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['ksh'] = 'Kölsch', -- MediaWiki: Colognian; use IANA/ISO 639 preferred name
['ksh-x-colog'] = 'Colognian', -- override MediaWiki ksh; no IANA/ISO 639 code for Colognian; IETF private code created at Module:Lang/data
['mis-x-ripuar'] = 'Ripuarian', -- override MediaWiki ksh; no IANA/ISO 639 code for Ripuarian; IETF private code created at Module:Lang/data
['nan-tw'] = 'Taiwanese Hokkien', -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese and support en.wiki preferred name
}
local lang_name_remap = { -- used for |language=; names require proper capitalization; tags must be lowercase
['alemannisch'] = {'Swiss German', 'gsw'}, -- not an ISO or IANA language name; MediaWiki uses 'als' as a subdomain name for Alemannic Wikipedia: als.wikipedia.org
['bangla'] = {'Bengali', 'bn'}, -- MediaWiki returns Bangla (the endonym) but we want Bengali (the exonym); here we remap
['bengali'] = {'Bengali', 'bn'}, -- MediaWiki doesn't use exonym so here we provide correct language name and 639-1 code
['bhojpuri'] = {'Bhojpuri', 'bho'}, -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bihari'] = {'Bihari', 'bh'}, -- MediaWiki replaces 'Bihari' with 'Bhojpuri' so 'Bihari' cannot be found
['blackfoot'] = {'Blackfoot', 'bla'}, -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['colognian'] = {'Colognian', 'ksh-x-colog'}, -- MediaWiki preferred name for ksh
['ilocano'] = {'Ilocano', 'ilo'}, -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['kolsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name (use non-diacritical o instead of umlaut ö)
['kölsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name
['ripuarian'] = {'Ripuarian', 'mis-x-ripuar'}, -- group of dialects; no code in MediaWiki or in IANA/ISO 639
['taiwanese hokkien'] = {'Taiwanese Hokkien', 'nan-tw'}, -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese
['tosk albanian'] = {'Tosk Albanian', 'als'}, -- MediaWiki replaces 'Tosk Albanian' with 'Alemannisch' so 'Tosk Albanian' cannot be found
['valencian'] = {'Valencian', 'ca'}, -- variant of Catalan; categorizes as Catalan
}
--[[---------------< P R O P E R T I E S _ C A T E G O R I E S >----------------
Properties categories. These are used for investigating qualities of citations.
]]
local prop_cats = {
['foreign-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is foreign-language name, $2 is ISO639-1 code
['foreign-lang-source-2'] = 'CS1 foreign language sources (ISO 639-2)|$1', -- |language= category; a cat for ISO639-2 languages; $1 is the ISO 639-2 code used as a sort key
['jul-greg-uncertainty'] = 'CS1: Julian–Gregorian uncertainty', -- probably temporary cat to identify scope of template with dates 1 October 1582 – 1 January 1926
['local-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is local-language name, $2 is ISO639-1 code; not emitted when local_lang_cat_enable is false
['location-test'] = 'CS1 location test',
['long-vol'] = 'CS1: long volume value', -- probably temporary cat to identify scope of |volume= values longer than 4 charachters
['script'] = 'CS1 uses $1-language script ($2)', -- |script-title=xx: has matching category; $1 is language name, $2 is ISO639-1 code
['tracked-param'] = 'CS1 tracked parameter: $1', -- $1 is base (enumerators removed) parameter name
['year-range-abbreviated'] = 'CS1: abbreviated year range', -- probably temporary cat to identify scope of |date=, |year= values using YYYY–YY form
}
--[[-------------------< T I T L E _ T Y P E S >--------------------------------
Here we map a template's CitationClass to TitleType (default values for |type= parameter)
]]
local title_types = {
['AV-media-notes'] = 'Media notes',
['interview'] = 'Interview',
['mailinglist'] = 'Mailing list',
['map'] = 'Map',
['podcast'] = 'Podcast',
['pressrelease'] = 'Press release',
['report'] = 'Report',
['speech'] = 'Speech',
['techreport'] = 'Technical report',
['thesis'] = 'Thesis',
}
--[[===================<< E R R O R M E S S A G I N G >>======================
]]
--[[----------< E R R O R M E S S A G E S U P P L I M E N T S >-------------
I18N for those messages that are supplemented with additional specific text that
describes the reason for the error
TODO: merge this with special_case_translations{}?
]]
local err_msg_supl = {
['char'] = 'invalid character', -- |isbn=, |sbn=
['check'] = 'checksum', -- |isbn=, |sbn=
['flag'] = 'flag', -- |archive-url=
['form'] = 'invalid form', -- |isbn=, |sbn=
['group'] = 'invalid group id', -- |isbn=
['initials'] = 'initials', -- Vancouver
['invalid language code'] = 'invalid language code', -- |script-<param>=
['journal'] = 'journal', -- |bibcode=
['length'] = 'length', -- |isbn=, |bibcode=, |sbn=
['liveweb'] = 'liveweb', -- |archive-url=
['missing comma'] = 'missing comma', -- Vancouver
['missing prefix'] = 'missing prefix', -- |script-<param>=
['missing title part'] = 'missing title part', -- |script-<param>=
['name'] = 'name', -- Vancouver
['non-Latin char'] = 'non-Latin character', -- Vancouver
['path'] = 'path', -- |archive-url=
['prefix'] = 'invalid prefix', -- |isbn=
['punctuation'] = 'punctuation', -- Vancouver
['save'] = 'save command', -- |archive-url=
['suffix'] = 'suffix', -- Vancouver
['timestamp'] = 'timestamp', -- |archive-url=
['unknown language code'] = 'unknown language code', -- |script-<param>=
['value'] = 'value', -- |bibcode=
['year'] = 'year', -- |bibcode=
}
--[[--------------< E R R O R _ C O N D I T I O N S >---------------------------
Error condition table. This table has two sections: errors at the top, maintenance
at the bottom. Maint 'messaging' does not have a 'message' (message=nil)
The following contains a list of IDs for various error conditions defined in the
code. For each ID, we specify a text message to display, an error category to
include, and whether the error message should be wrapped as a hidden comment.
Anchor changes require identical changes to matching anchor in Help:CS1 errors
TODO: rename error_conditions{} to something more generic; create separate error
and maint tables inside that?
]]
local error_conditions = {
err_accessdate_missing_url = {
message = '<code class="cs1-code">|access-date=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'accessdate_missing_url',
category = 'CS1 errors: access-date without URL',
hidden = false
},
err_apostrophe_markup = {
message = 'Italic or bold markup not allowed in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'apostrophe_markup',
category = 'CS1 errors: markup',
hidden = false
},
err_archive_missing_date = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|archive-date=</code>',
anchor = 'archive_missing_date',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_url = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'archive_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_url = {
message = '<code class="cs1-code">|archive-url=</code> is malformed: $1', -- $1 is error message detail
anchor = 'archive_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_arxiv_missing = {
message = '<code class="cs1-code">|arxiv=</code> required',
anchor = 'arxiv_missing',
category = 'CS1 errors: arXiv', -- same as bad arxiv
hidden = false
},
err_asintld_missing_asin = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|asin=</code>', -- $1 is parameter name
anchor = 'asintld_missing_asin',
category = 'CS1 errors: ASIN TLD',
hidden = false
},
err_bad_arxiv = {
message = 'Check <code class="cs1-code">|arxiv=</code> value',
anchor = 'bad_arxiv',
category = 'CS1 errors: arXiv',
hidden = false
},
err_bad_asin = {
message = 'Check <code class="cs1-code">|asin=</code> value',
anchor = 'bad_asin',
category ='CS1 errors: ASIN',
hidden = false
},
err_bad_asin_tld = {
message = 'Check <code class="cs1-code">|asin-tld=</code> value',
anchor = 'bad_asin_tld',
category ='CS1 errors: ASIN TLD',
hidden = false
},
err_bad_bibcode = {
message = 'Check <code class="cs1-code">|bibcode=</code> $1', -- $1 is error message detail
anchor = 'bad_bibcode',
category = 'CS1 errors: bibcode',
hidden = false
},
err_bad_biorxiv = {
message = 'Check <code class="cs1-code">|biorxiv=</code> value',
anchor = 'bad_biorxiv',
category = 'CS1 errors: bioRxiv',
hidden = false
},
err_bad_citeseerx = {
message = 'Check <code class="cs1-code">|citeseerx=</code> value',
anchor = 'bad_citeseerx',
category = 'CS1 errors: citeseerx',
hidden = false
},
err_bad_date = {
message = 'Check date values in: $1', -- $1 is a parameter name list
anchor = 'bad_date',
category = 'CS1 errors: dates',
hidden = false
},
err_bad_doi = {
message = 'Check <code class="cs1-code">|doi=</code> value',
anchor = 'bad_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_bad_hdl = {
message = 'Check <code class="cs1-code">|hdl=</code> value',
anchor = 'bad_hdl',
category = 'CS1 errors: HDL',
hidden = false
},
err_bad_isbn = {
message = 'Check <code class="cs1-code">|isbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_isbn',
category = 'CS1 errors: ISBN',
hidden = false
},
err_bad_ismn = {
message = 'Check <code class="cs1-code">|ismn=</code> value',
anchor = 'bad_ismn',
category = 'CS1 errors: ISMN',
hidden = false
},
err_bad_issn = {
message = 'Check <code class="cs1-code">|$1issn=</code> value', -- $1 is 'e' or '' for eissn or issn
anchor = 'bad_issn',
category = 'CS1 errors: ISSN',
hidden = false
},
err_bad_jfm = {
message = 'Check <code class="cs1-code">|jfm=</code> value',
anchor = 'bad_jfm',
category = 'CS1 errors: JFM',
hidden = false
},
err_bad_jstor = {
message = 'Check <code class="cs1-code">|jstor=</code> value',
anchor = 'bad_jstor',
category = 'CS1 errors: JSTOR',
hidden = false
},
err_bad_lccn = {
message = 'Check <code class="cs1-code">|lccn=</code> value',
anchor = 'bad_lccn',
category = 'CS1 errors: LCCN',
hidden = false
},
err_bad_mr = {
message = 'Check <code class="cs1-code">|mr=</code> value',
anchor = 'bad_mr',
category = 'CS1 errors: MR',
hidden = false
},
err_bad_oclc = {
message = 'Check <code class="cs1-code">|oclc=</code> value',
anchor = 'bad_oclc',
category = 'CS1 errors: OCLC',
hidden = false
},
err_bad_ol = {
message = 'Check <code class="cs1-code">|ol=</code> value',
anchor = 'bad_ol',
category = 'CS1 errors: OL',
hidden = false
},
err_bad_osti = {
message = 'Check <code class="cs1-code">|osti=</code> value',
anchor = 'bad_osti',
category = 'CS1 errors: OSTI',
hidden = false
},
err_bad_paramlink = { -- for |title-link=, |author/editor/translator-link=, |series-link=, |episode-link=
message = 'Check <code class="cs1-code">|$1=</code> value', -- $1 is parameter name
anchor = 'bad_paramlink',
category = 'CS1 errors: parameter link',
hidden = false
},
err_bad_pmc = {
message = 'Check <code class="cs1-code">|pmc=</code> value',
anchor = 'bad_pmc',
category = 'CS1 errors: PMC',
hidden = false
},
err_bad_pmid = {
message = 'Check <code class="cs1-code">|pmid=</code> value',
anchor = 'bad_pmid',
category = 'CS1 errors: PMID',
hidden = false
},
err_bad_rfc = {
message = 'Check <code class="cs1-code">|rfc=</code> value',
anchor = 'bad_rfc',
category = 'CS1 errors: RFC',
hidden = false
},
err_bad_s2cid = {
message = 'Check <code class="cs1-code">|s2cid=</code> value',
anchor = 'bad_s2cid',
category = 'CS1 errors: S2CID',
hidden = false
},
err_bad_sbn = {
message = 'Check <code class="cs1-code">|sbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_sbn',
category = 'CS1 errors: SBN',
hidden = false
},
err_bad_ssrn = {
message = 'Check <code class="cs1-code">|ssrn=</code> value',
anchor = 'bad_ssrn',
category = 'CS1 errors: SSRN',
hidden = false
},
err_bad_url = {
message = 'Check $1 value', -- $1 is parameter name
anchor = 'bad_url',
category = 'CS1 errors: URL',
hidden = false
},
err_bad_usenet_id = {
message = 'Check <code class="cs1-code">|message-id=</code> value',
anchor = 'bad_message_id',
category = 'CS1 errors: message-id',
hidden = false
},
err_bad_zbl = {
message = 'Check <code class="cs1-code">|zbl=</code> value',
anchor = 'bad_zbl',
category = 'CS1 errors: Zbl',
hidden = false
},
err_bare_url_missing_title = {
message = '$1 missing title', -- $1 is parameter name
anchor = 'bare_url_missing_title',
category = 'CS1 errors: bare URL',
hidden = false
},
err_biorxiv_missing = {
message = '<code class="cs1-code">|biorxiv=</code> required',
anchor = 'biorxiv_missing',
category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv
hidden = false
},
err_chapter_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'chapter_ignored',
category = 'CS1 errors: chapter ignored',
hidden = false
},
err_citation_missing_title = {
message = 'Missing or empty <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'citation_missing_title',
category = 'CS1 errors: missing title',
hidden = false
},
err_citeseerx_missing = {
message = '<code class="cs1-code">|citeseerx=</code> required',
anchor = 'citeseerx_missing',
category = 'CS1 errors: citeseerx', -- same as bad citeseerx
hidden = false
},
err_cite_web_url = { -- this error applies to cite web and to cite podcast
message = 'Missing or empty <code class="cs1-code">|url=</code>',
anchor = 'cite_web_url',
category = 'CS1 errors: requires URL',
hidden = false
},
err_class_ignored = {
message = '<code class="cs1-code">|class=</code> ignored',
anchor = 'class_ignored',
category = 'CS1 errors: class',
hidden = false
},
err_contributor_ignored = {
message = '<code class="cs1-code">|contributor=</code> ignored',
anchor = 'contributor_ignored',
category = 'CS1 errors: contributor',
hidden = false
},
err_contributor_missing_required_param = {
message = '<code class="cs1-code">|contributor=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'contributor_missing_required_param',
category = 'CS1 errors: contributor',
hidden = false
},
err_deprecated_params = {
message = 'Cite uses deprecated parameter <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'deprecated_params',
category = 'CS1 errors: deprecated parameters',
hidden = false
},
err_disp_name = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name; $2 is the assigned value
anchor = 'disp_name',
category = 'CS1 errors: display-names',
hidden = false,
},
err_doibroken_missing_doi = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|doi=</code>', -- $1 is parameter name
anchor = 'doibroken_missing_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_embargo_missing_pmc = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|pmc=</code>', -- $1 is parameter name
anchor = 'embargo_missing_pmc',
category = 'CS1 errors: PMC embargo',
hidden = false
},
err_empty_citation = {
message = 'Empty citation',
anchor = 'empty_citation',
category = 'CS1 errors: empty citation',
hidden = false
},
err_etal = {
message = 'Explicit use of et al. in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'explicit_et_al',
category = 'CS1 errors: explicit use of et al.',
hidden = false
},
err_extra_text_edition = {
message = '<code class="cs1-code">|edition=</code> has extra text',
anchor = 'extra_text_edition',
category = 'CS1 errors: extra text: edition',
hidden = false,
},
err_extra_text_issue = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_issue',
category = 'CS1 errors: extra text: issue',
hidden = false,
},
err_extra_text_pages = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_pages',
category = 'CS1 errors: extra text: pages',
hidden = false,
},
err_extra_text_volume = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_volume',
category = 'CS1 errors: extra text: volume',
hidden = true,
},
err_first_missing_last = {
message = '<code class="cs1-code">|$1=</code> missing <code class="cs1-code">|$2=</code>', -- $1 is first alias, $2 is matching last alias
anchor = 'first_missing_last',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_format_missing_url = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|$2=</code>', -- $1 is format parameter $2 is url parameter
anchor = 'format_missing_url',
category = 'CS1 errors: format without URL',
hidden = false
},
err_generic_name = {
message = '<code class="cs1-code">|$1=</code> has generic name', -- $1 is parameter name
anchor = 'generic_name',
category = 'CS1 errors: generic name',
hidden = false,
},
err_generic_title = {
message = 'Cite uses generic title',
anchor = 'generic_title',
category = 'CS1 errors: generic title',
hidden = false,
},
err_invalid_param_val = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name $2 is parameter value
anchor = 'invalid_param_val',
category = 'CS1 errors: invalid parameter value',
hidden = false
},
err_invisible_char = {
message = '$1 in $2 at position $3', -- $1 is invisible char $2 is parameter name $3 is position number
anchor = 'invisible_char',
category = 'CS1 errors: invisible characters',
hidden = false
},
err_missing_name = {
message = 'Missing <code class="cs1-code">|$1$2=</code>', -- $1 is modified NameList; $2 is enumerator
anchor = 'missing_name',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_missing_periodical = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical periodical parameter name for cite $1
anchor = 'missing_periodical',
category = 'CS1 errors: missing periodical',
hidden = true
},
err_missing_pipe = {
message = 'Missing pipe in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'missing_pipe',
category = 'CS1 errors: missing pipe',
hidden = false
},
err_param_access_requires_param = {
message = '<code class="cs1-code">|$1-access=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'param_access_requires_param',
category = 'CS1 errors: param-access',
hidden = false
},
err_param_has_ext_link = {
message = 'External link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_ext_link',
category = 'CS1 errors: external links',
hidden = false
},
err_parameter_ignored = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'parameter_ignored',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_parameter_ignored_suggest = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored (<code class="cs1-code">|$2=</code> suggested)', -- $1 is unknown parameter $2 is suggested parameter name
anchor = 'parameter_ignored_suggest',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_redundant_parameters = {
message = 'More than one of $1 specified', -- $1 is error message detail
anchor = 'redundant_parameters',
category = 'CS1 errors: redundant parameter',
hidden = false
},
err_script_parameter = {
message = 'Invalid <code class="cs1-code">|$1=</code>: $2', -- $1 is parameter name $2 is script language code or error detail
anchor = 'script_parameter',
category = 'CS1 errors: script parameters',
hidden = false
},
err_ssrn_missing = {
message = '<code class="cs1-code">|ssrn=</code> required',
anchor = 'ssrn_missing',
category = 'CS1 errors: SSRN', -- same as bad arxiv
hidden = false
},
err_text_ignored = {
message = 'Text "$1" ignored', -- $1 is ignored text
anchor = 'text_ignored',
category = 'CS1 errors: unrecognized parameter',
hidden = false
},
err_trans_missing_title = {
message = '<code class="cs1-code">|trans-$1=</code> requires <code class="cs1-code">|$1=</code> or <code class="cs1-code">|script-$1=</code>', -- $1 is base parameter name
anchor = 'trans_missing_title',
category = 'CS1 errors: translated title',
hidden = false
},
err_param_unknown_empty = {
message = 'Cite has empty unknown parameter$1: $2', -- $1 is 's' or empty space; $2 is emty unknown param list
anchor = 'param_unknown_empty',
category = 'CS1 errors: empty unknown parameters',
hidden = false
},
err_vancouver = {
message = 'Vancouver style error: $1 in name $2', -- $1 is error detail, $2 is the nth name
anchor = 'vancouver',
category = 'CS1 errors: Vancouver style',
hidden = false
},
err_wikilink_in_url = {
message = 'URL–wikilink conflict', -- uses ndash
anchor = 'wikilink_in_url',
category = 'CS1 errors: URL–wikilink conflict', -- uses ndash
hidden = false
},
--[[--------------------------< M A I N T >-------------------------------------
maint messages do not have a message (message = nil); otherwise the structure
is the same as error messages
]]
maint_archived_copy = {
message = nil,
anchor = 'archived_copy',
category = 'CS1 maint: archived copy as title',
hidden = true,
},
maint_authors = {
message = nil,
anchor = 'authors',
category = 'CS1 maint: uses authors parameter',
hidden = true,
},
maint_bot_unknown = {
message = nil,
anchor = 'bot:_unknown',
category = 'CS1 maint: bot: original URL status unknown',
hidden = true,
},
maint_date_auto_xlated = { -- date auto-translation not supported by en.wiki
message = nil,
anchor = 'date_auto_xlated',
category = 'CS1 maint: date auto-translated',
hidden = true,
},
maint_date_format = {
message = nil,
anchor = 'date_format',
category = 'CS1 maint: date format',
hidden = true,
},
maint_date_year = {
message = nil,
anchor = 'date_year',
category = 'CS1 maint: date and year',
hidden = true,
},
maint_doi_ignore = {
message = nil,
anchor = 'doi_ignore',
category = 'CS1 maint: ignored DOI errors',
hidden = true,
},
maint_doi_inactive = {
message = nil,
anchor = 'doi_inactive',
category = 'CS1 maint: DOI inactive',
hidden = true,
},
maint_doi_inactive_dated = {
message = nil,
anchor = 'doi_inactive_dated',
category = 'CS1 maint: DOI inactive as of $2$3$1', -- $1 is year, $2 is month-name or empty string, $3 is space or empty string
hidden = true,
},
maint_extra_punct = {
message = nil,
anchor = 'extra_punct',
category = 'CS1 maint: extra punctuation',
hidden = true,
},
maint_isbn_ignore = {
message = nil,
anchor = 'ignore_isbn_err',
category = 'CS1 maint: ignored ISBN errors',
hidden = true,
},
maint_issn_ignore = {
message = nil,
anchor = 'ignore_issn',
category = 'CS1 maint: ignored ISSN errors',
hidden = true,
},
maint_jfm_format = {
message = nil,
anchor = 'jfm_format',
category = 'CS1 maint: JFM format',
hidden = true,
},
maint_location = {
message = nil,
anchor = 'location',
category = 'CS1 maint: location',
hidden = true,
},
maint_mr_format = {
message = nil,
anchor = 'mr_format',
category = 'CS1 maint: MR format',
hidden = true,
},
maint_mult_names = {
message = nil,
anchor = 'mult_names',
category = 'CS1 maint: multiple names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_numeric_names = {
message = nil,
anchor = 'numeric_names',
category = 'CS1 maint: numeric names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_others = {
message = nil,
anchor = 'others',
category = 'CS1 maint: others',
hidden = true,
},
maint_others_avm = {
message = nil,
anchor = 'others_avm',
category = 'CS1 maint: others in cite AV media (notes)',
hidden = true,
},
maint_pmc_embargo = {
message = nil,
anchor = 'embargo',
category = 'CS1 maint: PMC embargo expired',
hidden = true,
},
maint_pmc_format = {
message = nil,
anchor = 'pmc_format',
category = 'CS1 maint: PMC format',
hidden = true,
},
maint_postscript = {
message = nil,
anchor = 'postscript',
category = 'CS1 maint: postscript',
hidden = true,
},
maint_ref_duplicates_default = {
message = nil,
anchor = 'ref_default',
category = 'CS1 maint: ref duplicates default',
hidden = true,
},
maint_unfit = {
message = nil,
anchor = 'unfit',
category = 'CS1 maint: unfit URL',
hidden = true,
},
maint_unknown_lang = {
message = nil,
anchor = 'unknown_lang',
category = 'CS1 maint: unrecognized language',
hidden = true,
},
maint_untitled = {
message = nil,
anchor = 'untitled',
category = 'CS1 maint: untitled periodical',
hidden = true,
},
maint_url_status = {
message = nil,
anchor = 'url_status',
category = 'CS1 maint: url-status',
hidden = true,
},
maint_zbl = {
message = nil,
anchor = 'zbl',
category = 'CS1 maint: Zbl',
hidden = true,
},
}
--[[--------------------------< I D _ H A N D L E R S >--------------------------------------------------------
The following contains a list of values for various defined identifiers. For each
identifier we specify a variety of information necessary to properly render the
identifier in the citation.
parameters: a list of parameter aliases for this identifier; first in the list is the canonical form
link: Wikipedia article name
redirect: a local redirect to a local Wikipedia article name; at en.wiki, 'ISBN (identifier)' is a redirect to 'International Standard Book Number'
q: Wikidata q number for the identifier
label: the label preceeding the identifier; label is linked to a Wikipedia article (in this order):
redirect from id_handlers['<id>'].redirect when use_identifier_redirects is true
Wikidata-supplied article name for the local wiki from id_handlers['<id>'].q
local article name from id_handlers['<id>'].link
prefix: the first part of a URL that will be concatenated with a second part which usually contains the identifier
suffix: optional third part to be added after the identifier
encode: true if URI should be percent-encoded; otherwise false
COinS: identifier link or keyword for use in COinS:
for identifiers registered at info-uri.info use: info:.... where '...' is the appropriate identifier label
for identifiers that have COinS keywords, use the keyword: rft.isbn, rft.issn, rft.eissn
for |asin= and |ol=, which require assembly, use the keyword: url
for others make a URL using the value in prefix/suffix and #label, use the keyword: pre (not checked; any text other than 'info', 'rft', or 'url' works here)
set to nil to leave the identifier out of the COinS
separator: character or text between label and the identifier in the rendered citation
id_limit: for those identifiers with established limits, this property holds the upper limit
access: use this parameter to set the access level for all instances of this identifier.
the value must be a valid access level for an identifier (see ['id-access'] in this file).
custom_access: to enable custom access level for an identifier, set this parameter
to the parameter that should control it (normally 'id-access')
]]
local id_handlers = {
['ARXIV'] = {
parameters = {'arxiv', 'eprint'},
link = 'arXiv',
redirect = 'arXiv (identifier)',
q = 'Q118398',
label = 'arXiv',
prefix = '//arxiv.org/abs/', -- protocol-relative tested 2013-09-04
encode = false,
COinS = 'info:arxiv',
separator = ':',
access = 'free', -- free to read
},
['ASIN'] = {
parameters = { 'asin', 'ASIN' },
link = 'Amazon Standard Identification Number',
redirect = 'ASIN (identifier)',
q = 'Q1753278',
label = 'ASIN',
prefix = '//www.amazon.',
COinS = 'url',
separator = ' ',
encode = false;
},
['BIBCODE'] = {
parameters = {'bibcode'},
link = 'Bibcode',
redirect = 'Bibcode (identifier)',
q = 'Q25754',
label = 'Bibcode',
prefix = 'https://ui.adsabs.harvard.edu/abs/',
encode = false,
COinS = 'info:bibcode',
separator = ':',
custom_access = 'bibcode-access',
},
['BIORXIV'] = {
parameters = {'biorxiv'},
link = 'bioRxiv',
redirect = 'bioRxiv (identifier)',
q = 'Q19835482',
label = 'bioRxiv',
prefix = '//doi.org/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['CITESEERX'] = {
parameters = {'citeseerx'},
link = 'CiteSeerX',
redirect = 'CiteSeerX (identifier)',
q = 'Q2715061',
label = 'CiteSeerX',
prefix = '//citeseerx.ist.psu.edu/viewdoc/summary?doi=',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['DOI'] = { -- Used by InternetArchiveBot
parameters = { 'doi', 'DOI'},
link = 'Digital object identifier',
redirect = 'doi (identifier)',
q = 'Q25670',
label = 'doi',
prefix = '//doi.org/',
COinS = 'info:doi',
separator = ':',
encode = true,
custom_access = 'doi-access',
},
['EISSN'] = {
parameters = {'eissn', 'EISSN'},
link = 'International Standard Serial Number#Electronic ISSN',
redirect = 'eISSN (identifier)',
q = 'Q46339674',
label = 'eISSN',
prefix = '//www.worldcat.org/issn/',
COinS = 'rft.eissn',
encode = false,
separator = ' ',
},
['HDL'] = {
parameters = { 'hdl', 'HDL' },
link = 'Handle System',
redirect = 'hdl (identifier)',
q = 'Q3126718',
label = 'hdl',
prefix = '//hdl.handle.net/',
COinS = 'info:hdl',
separator = ':',
encode = true,
custom_access = 'hdl-access',
},
['ISBN'] = { -- Used by InternetArchiveBot
parameters = {'isbn', 'ISBN'},
link = 'International Standard Book Number',
redirect = 'ISBN (identifier)',
q = 'Q33057',
label = 'ISBN',
prefix = 'Special:BookSources/',
COinS = 'rft.isbn',
separator = ' ',
},
['ISMN'] = {
parameters = {'ismn', 'ISMN'},
link = 'International Standard Music Number',
redirect = 'ISMN (identifier)',
q = 'Q1666938',
label = 'ISMN',
prefix = '', -- not currently used;
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['ISSN'] = {
parameters = {'issn', 'ISSN'},
link = 'International Standard Serial Number',
redirect = 'ISSN (identifier)',
q = 'Q131276',
label = 'ISSN',
prefix = '//www.worldcat.org/issn/',
COinS = 'rft.issn',
encode = false,
separator = ' ',
},
['JFM'] = {
parameters = {'jfm', 'JFM'},
link = 'Jahrbuch über die Fortschritte der Mathematik',
redirect = 'JFM (identifier)',
q = '',
label = 'JFM',
prefix = '//zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['JSTOR'] = {
parameters = {'jstor', 'JSTOR'},
link = 'JSTOR',
redirect = 'JSTOR (identifier)',
q = 'Q1420342',
label = 'JSTOR',
prefix = '//www.jstor.org/stable/', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
custom_access = 'jstor-access',
},
['LCCN'] = {
parameters = {'lccn', 'LCCN'},
link = 'Library of Congress Control Number',
redirect = 'LCCN (identifier)',
q = 'Q620946',
label = 'LCCN',
prefix = '//lccn.loc.gov/', -- protocol-relative tested 2015-12-28
COinS = 'info:lccn',
encode = false,
separator = ' ',
},
['MR'] = {
parameters = {'mr', 'MR'},
link = 'Mathematical Reviews',
redirect = 'MR (identifier)',
q = 'Q211172',
label = 'MR',
prefix = '//www.ams.org/mathscinet-getitem?mr=', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['OCLC'] = {
parameters = {'oclc', 'OCLC'},
link = 'OCLC',
redirect = 'OCLC (identifier)',
q = 'Q190593',
label = 'OCLC',
prefix = '//www.worldcat.org/oclc/',
COinS = 'info:oclcnum',
encode = true,
separator = ' ',
id_limit = 9999999999, -- 10-digits
},
['OL'] = {
parameters = { 'ol', 'OL' },
link = 'Open Library',
redirect = 'OL (identifier)',
q = 'Q1201876',
label = 'OL',
prefix = '//openlibrary.org/',
COinS = 'url',
separator = ' ',
encode = true,
custom_access = 'ol-access',
},
['OSTI'] = {
parameters = {'osti', 'OSTI'},
link = 'Office of Scientific and Technical Information',
redirect = 'OSTI (identifier)',
q = 'Q2015776',
label = 'OSTI',
prefix = '//www.osti.gov/biblio/', -- protocol-relative tested 2018-09-12
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 23010000,
custom_access = 'osti-access',
},
['PMC'] = {
parameters = {'pmc', 'PMC'},
link = 'PubMed Central',
redirect = 'PMC (identifier)',
q = 'Q229883',
label = 'PMC',
prefix = '//www.ncbi.nlm.nih.gov/pmc/articles/PMC',
suffix = '',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 9500000,
access = 'free', -- free to read
},
['PMID'] = {
parameters = {'pmid', 'PMID'},
link = 'PubMed Identifier',
redirect = 'PMID (identifier)',
q = 'Q2082879',
label = 'PMID',
prefix = '//pubmed.ncbi.nlm.nih.gov/',
COinS = 'info:pmid',
encode = false,
separator = ' ',
id_limit = 36400000,
},
['RFC'] = {
parameters = {'rfc', 'RFC'},
link = 'Request for Comments',
redirect = 'RFC (identifier)',
q = 'Q212971',
label = 'RFC',
prefix = '//tools.ietf.org/html/rfc',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = 9300,
access = 'free', -- free to read
},
['SBN'] = {
parameters = {'sbn', 'SBN'},
link = 'Standard Book Number', -- redirect to International_Standard_Book_Number#History
redirect = 'SBN (identifier)',
label = 'SBN',
prefix = 'Special:BookSources/0-', -- prefix has leading zero necessary to make 9-digit sbn a 10-digit isbn
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['SSRN'] = {
parameters = {'ssrn', 'SSRN'},
link = 'Social Science Research Network',
redirect = 'SSRN (identifier)',
q = 'Q7550801',
label = 'SSRN',
prefix = '//ssrn.com/abstract=', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 4200000,
custom_access = 'ssrn-access',
},
['S2CID'] = {
parameters = {'s2cid', 'S2CID'},
link = 'Semantic Scholar',
redirect = 'S2CID (identifier)',
q = 'Q22908627',
label = 'S2CID',
prefix = 'https://api.semanticscholar.org/CorpusID:',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = 254000000,
custom_access = 's2cid-access',
},
['USENETID'] = {
parameters = {'message-id'},
link = 'Usenet',
redirect = 'Usenet (identifier)',
q = 'Q193162',
label = 'Usenet:',
prefix = 'news:',
encode = false,
COinS = 'pre', -- use prefix value
separator = ' ',
},
['ZBL'] = {
parameters = {'zbl', 'ZBL' },
link = 'Zentralblatt MATH',
redirect = 'Zbl (identifier)',
q = 'Q190269',
label = 'Zbl',
prefix = '//zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
}
--[[--------------------------< E X P O R T S >---------------------------------
]]
return {
use_identifier_redirects = true, -- when true use redirect name for identifier label links; always true at en.wiki
local_lang_cat_enable = false; -- when true categorizes pages where |language=<local wiki's language>; always false at en.wiki
date_name_auto_xlate_enable = false; -- when true translates English month-names to the local-wiki's language month names; always false at en.wiki
date_digit_auto_xlate_enable = false; -- when true translates Western date digit to the local-wiki's language digits (date_names['local_digits']); always false at en.wiki
global_df = get_date_format (), -- tables and variables created when this module is loaded
punct_skip = build_skip_table (punct_skip, punct_meta_params),
url_skip = build_skip_table (url_skip, url_meta_params),
aliases = aliases,
special_case_translation = special_case_translation,
date_names = date_names,
err_msg_supl = err_msg_supl,
error_conditions = error_conditions,
editor_markup_patterns = editor_markup_patterns,
et_al_patterns = et_al_patterns,
id_handlers = id_handlers,
keywords_lists = keywords_lists,
keywords_xlate = keywords_xlate,
stripmarkers=stripmarkers,
invisible_chars = invisible_chars,
invisible_defs = invisible_defs,
indic_script = indic_script,
emoji = emoji,
maint_cats = maint_cats,
messages = messages,
presentation = presentation,
prop_cats = prop_cats,
script_lang_codes = script_lang_codes,
lang_code_remap = lang_code_remap,
lang_name_remap = lang_name_remap,
this_wiki_code = this_wiki_code,
title_types = title_types,
uncategorized_namespaces = uncategorized_namespaces,
uncategorized_subpages = uncategorized_subpages,
templates_using_volume = templates_using_volume,
templates_using_issue = templates_using_issue,
templates_not_using_page = templates_not_using_page,
vol_iss_pg_patterns = vol_iss_pg_patterns,
inter_wiki_map = inter_wiki_map,
mw_languages_by_tag_t = mw_languages_by_tag_t,
mw_languages_by_name_t = mw_languages_by_name_t,
citation_class_map_t = citation_class_map_t,
citation_issue_t = citation_issue_t,
citation_no_volume_t = citation_no_volume_t,
}
eece11b3085eb39f5bb266336c4c5afa7a6eaa74
Template:Sclass/core
10
129
273
2022-08-04T14:50:18Z
Canopus >Dinoguy1000
0
simplify code a bit
wikitext
text/x-wiki
<includeonly>[[{{{1}}}-class {{{2}}} {{#if:{{{5|}}}|({{{5}}})}}|{{#switch:{{{format}}}
|sclass =''{{{1}}}''
|sclass2 ={{{1}}}
}}<!--
-->{{#switch:{{{3|}}}
|=-class]] [[{{#if:{{{4|}}}|{{{2}}} ({{{4}}}){{!}}{{{2}}}|{{{2}}}}}]]
|0 =-class]]
|1 =-class {{{2}}}]]
|2 =-class]] {{{2}}}
|3 =-class]] [[{{#if:{{{4|}}}|{{{2}}} ({{{4}}}){{!}}{{{2}}}|{{{2}}}}}]]
|4 = class]]
|5 =]]
|6|#default=-class {{{2}}}]]<!-- same as 1, 3; warning + cat
-->{{preview warning|[[Template:{{{format|}}}|Template {{ucfirst:{{{format|}}}}}]], invalid format code: {{{3|}}}. Should be 1–5, or blank.}}{{main other|[[Category:WPSHIPS: sclass invalid option]]}}<!--
-->}}<!-- eo switch
--></includeonly><noinclude>{{documentation}}</noinclude>
d536aa9b427477a08e0d51d8dc68ef00c5c82098
Module:Hatnote
828
107
229
2022-08-18T19:31:48Z
Canopus >Nihiltres
0
Updated from sandbox: export default classes through new function p.defaultClasses
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Hatnote --
-- --
-- This module produces hatnote links and links to related articles. It --
-- implements the {{hatnote}} and {{format link}} meta-templates and includes --
-- helper functions for other Lua hatnote modules. --
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- lazily initialise [[Module:Arguments]]
local yesno -- lazily initialise [[Module:Yesno]]
local formatLink -- lazily initialise [[Module:Format link]] ._formatLink
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local curNs = mw.title.getCurrentTitle().namespace
p.missingTargetCat =
--Default missing target category, exported for use in related modules
((curNs == 0) or (curNs == 14)) and
'Articles with hatnote templates targeting a nonexistent page' or nil
local function getArgs(frame)
-- Fetches the arguments from the parent frame. Whitespace is trimmed and
-- blanks are removed.
mArguments = require('Module:Arguments')
return mArguments.getArgs(frame, {parentOnly = true})
end
local function removeInitialColon(s)
-- Removes the initial colon from a string, if present.
return s:match('^:?(.*)')
end
function p.findNamespaceId(link, removeColon)
-- Finds the namespace id (namespace number) of a link or a pagename. This
-- function will not work if the link is enclosed in double brackets. Colons
-- are trimmed from the start of the link by default. To skip colon
-- trimming, set the removeColon parameter to false.
checkType('findNamespaceId', 1, link, 'string')
checkType('findNamespaceId', 2, removeColon, 'boolean', true)
if removeColon ~= false then
link = removeInitialColon(link)
end
local namespace = link:match('^(.-):')
if namespace then
local nsTable = mw.site.namespaces[namespace]
if nsTable then
return nsTable.id
end
end
return 0
end
function p.makeWikitextError(msg, helpLink, addTrackingCategory, title)
-- Formats an error message to be returned to wikitext. If
-- addTrackingCategory is not false after being returned from
-- [[Module:Yesno]], and if we are not on a talk page, a tracking category
-- is added.
checkType('makeWikitextError', 1, msg, 'string')
checkType('makeWikitextError', 2, helpLink, 'string', true)
yesno = require('Module:Yesno')
title = title or mw.title.getCurrentTitle()
-- Make the help link text.
local helpText
if helpLink then
helpText = ' ([[' .. helpLink .. '|help]])'
else
helpText = ''
end
-- Make the category text.
local category
if not title.isTalkPage -- Don't categorise talk pages
and title.namespace ~= 2 -- Don't categorise userspace
and yesno(addTrackingCategory) ~= false -- Allow opting out
then
category = 'Hatnote templates with errors'
category = mw.ustring.format(
'[[%s:%s]]',
mw.site.namespaces[14].name,
category
)
else
category = ''
end
return mw.ustring.format(
'<strong class="error">Error: %s%s.</strong>%s',
msg,
helpText,
category
)
end
function p.disambiguate(page, disambiguator)
-- Formats a page title with a disambiguation parenthetical,
-- i.e. "Example" → "Example (disambiguation)".
checkType('disambiguate', 1, page, 'string')
checkType('disambiguate', 2, disambiguator, 'string', true)
disambiguator = disambiguator or 'disambiguation'
return mw.ustring.format('%s (%s)', page, disambiguator)
end
function p.defaultClasses(inline)
-- Provides the default hatnote classes as a space-separated string; useful
-- for hatnote-manipulation modules like [[Module:Hatnote group]].
return
(inline == 1 and 'hatnote-inline' or 'hatnote') .. ' ' ..
'navigation-not-searchable'
end
--------------------------------------------------------------------------------
-- Hatnote
--
-- Produces standard hatnote text. Implements the {{hatnote}} template.
--------------------------------------------------------------------------------
function p.hatnote(frame)
local args = getArgs(frame)
local s = args[1]
if not s then
return p.makeWikitextError(
'no text specified',
'Template:Hatnote#Errors',
args.category
)
end
return p._hatnote(s, {
extraclasses = args.extraclasses,
selfref = args.selfref
})
end
function p._hatnote(s, options)
checkType('_hatnote', 1, s, 'string')
checkType('_hatnote', 2, options, 'table', true)
options = options or {}
local inline = options.inline
local hatnote = mw.html.create(inline == 1 and 'span' or 'div')
local extraclasses
if type(options.extraclasses) == 'string' then
extraclasses = options.extraclasses
end
hatnote
:attr('role', 'note')
:addClass(p.defaultClasses(inline))
:addClass(extraclasses)
:addClass(options.selfref and 'selfref' or nil)
:wikitext(s)
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Module:Hatnote/styles.css' }
} .. tostring(hatnote)
end
return p
7a49bd6a35a51b9e77a9c2c6f8f09a4738d7d68e
Module:Footnotes/whitelist
828
105
225
2022-08-19T19:09:59Z
Canopus >Renata3
0
+ batch from Activelydisinterested
Scribunto
text/plain
--[[--------------------------< W R A P P E R _ T E M P L A T E _ D E F A U L T S >----------------------------
A list of wrapper templates by their canonical names – spelling and capitalization is important. Each wrapper
template has a table of two values: [1] is the wrapper's default name-list as it is used in an anchor ID; [2] is
the default year. This table is indexed indirectly through the wrapper_templates table.
This table is not available externally.
]]
local wrapper_template_defaults = { -- keys are canonical template names
['Americana'] = {'Rines', '1920'}, -- tables with default name and default year
['Cite EB1911'] = {'Chisholm', '1911'}, -- tables with default name and default year
['EB1911'] = {'Chisholm', '1911'},
['EI3'] = {'FleetKrämerMatringeNawas', ''},
['ODNB'] = {'', ''}, -- there is no default anchor ID; this forces evaluation of {{cite ODNB}} redirects
}
--[[--------------------------< W R A P P E R _ T E M P L A T E _ D E F A U L T S _ V O L >--------------------
For wrapper templates that use |volume= to specify default name (often editor names) and year. Wrapper templates
are indexed by their canonical names – spelling and capitalization is important. Each wrapper template has a table
of values for every volume. Volumes may be indexed by Arabic or Roman numerals. Each volume index has a table of
twp values" [1] is the wrapper's default name-list as it is used in an anchor ID; [2] is the default year. Each
wrapper template in this table must have a ['default'] key for those occasions when |volume= is omitted or empty.
This table is indexed indirectly through the wrapper_templates table.
This table is not available externally.
]]
local wrapper_template_defaults_vol = { -- primary keys are canonical template names; TODO: do these keys have to be canonical template names?
['Cite Catholic Encyclopedia'] = { -- secondary keys are volume
['1'] = {'Herbermann', '1907'},
['2'] = {'Herbermann', '1907'},
['3'] = {'Herbermann', '1908'},
['4'] = {'Herbermann', '1908'},
['5'] = {'Herbermann', '1909'},
['6'] = {'Herbermann', '1909'},
['7'] = {'Herbermann', '1910'},
['8'] = {'Herbermann', '1910'},
['9'] = {'Herbermann', '1910'},
['10'] = {'Herbermann', '1911'},
['11'] = {'Herbermann', '1911'},
['12'] = {'Herbermann', '1911'},
['13'] = {'Herbermann', '1912'},
['14'] = {'Herbermann', '1912'},
['15'] = {'Herbermann', '1912'},
['default'] = {'Herbermann', '1913'},
},
['Cite EB9'] = {
['1'] = {'Baynes', '1878'}, ['I'] = {'Baynes', '1878'},
['2'] = {'Baynes', '1878'}, ['II'] = {'Baynes', '1878'},
['3'] = {'Baynes', '1878'}, ['III'] = {'Baynes', '1878'},
['4'] = {'Baynes', '1878'}, ['IV'] = {'Baynes', '1878'},
['5'] = {'Baynes', '1878'}, ['V'] = {'Baynes', '1878'},
['6'] = {'Baynes', '1878'}, ['VI'] = {'Baynes', '1878'},
['7'] = {'Baynes', '1878'}, ['VII'] = {'Baynes', '1878'},
['8'] = {'Baynes', '1878'}, ['VIII'] = {'Baynes', '1878'},
['9'] = {'Baynes', '1879'}, ['IX'] = {'Baynes', '1879'},
['10'] = {'Baynes', '1879'}, ['X'] = {'Baynes', '1879'},
['11'] = {'BaynesSmith', '1880'}, ['XI'] = {'BaynesSmith', '1880'},
['12'] = {'BaynesSmith', '1881'}, ['XII'] = {'BaynesSmith', '1881'},
['13'] = {'BaynesSmith', '1881'}, ['XIII'] = {'BaynesSmith', '1881'},
['14'] = {'BaynesSmith', '1882'}, ['XIV'] = {'BaynesSmith', '1882'},
['15'] = {'BaynesSmith', '1883'}, ['XV'] = {'BaynesSmith', '1883'},
['16'] = {'BaynesSmith', '1883'}, ['XVI'] = {'BaynesSmith', '1883'},
['17'] = {'BaynesSmith', '1884'}, ['XVII'] = {'BaynesSmith', '1884'},
['18'] = {'BaynesSmith', '1885'}, ['XVIII'] = {'BaynesSmith', '1885'},
['19'] = {'BaynesSmith', '1885'}, ['XIX'] = {'BaynesSmith', '1885'},
['20'] = {'BaynesSmith', '1886'}, ['XX'] = {'BaynesSmith', '1886'},
['21'] = {'BaynesSmith', '1886'}, ['XXI'] = {'BaynesSmith', '1886'},
['22'] = {'BaynesSmith', '1887'}, ['XXII'] = {'BaynesSmith', '1887'},
['23'] = {'BaynesSmith', '1888'}, ['XXIII'] = {'BaynesSmith', '1888'},
['24'] = {'BaynesSmith', '1888'}, ['XXIV'] = {'BaynesSmith', '1888'},
['default'] = {'Baynes', '1875–1889'},
},
['Encyclopaedia of Islam, New Edition'] = {
['1'] = {'GibbKramersLévi-ProvençalSchacht', '1960'},
['2'] = {'LewisPellatSchacht', '1965'},
['3'] = {'LewisMénagePellatSchacht', '1971'},
['4'] = {'van_DonzelLewisPellatBosworth', '1978'},
['5'] = {'Bosworthvan_DonzelLewisPellat', '1986'},
['6'] = {'Bosworthvan_DonzelPellat', '1991'},
['7'] = {'Bosworthvan_DonzelHeinrichsPellat', '1993'},
['8'] = {'Bosworthvan_DonzelHeinrichsLecomte', '1995'},
['9'] = {'Bosworthvan_DonzelHeinrichsLecomte', '1997'},
['10'] = {'BearmanBianquisBosworthvan_Donzel', '2000'},
['11'] = {'BearmanBianquisBosworthvan_Donzel', '2002'},
['12'] = {'BearmanBianquisBosworthvan_Donzel', '2004'},
['atlas'] = {'Brice', '1981'},
['abridged'] = {'van_Donzel', '1994'},
['default'] = {'BearmanBianquisBosworthvan_Donzel', '1960–2005'},
},
['New Cambridge Medieval History'] = {
['1'] = {'Fouracre', '2005'},
['2'] = {'McKitterick', '1995'},
['3'] = {'Reuter', '2000'},
['4a'] = {'LuscombeRiley-Smith', '2004'},
['4b'] = {'LuscombeRiley-Smith', '2004'},
['5'] = {'Abulafia', '1999'},
['6'] = {'Jones', '2000'},
['7'] = {'Allmand', '1998'},
['default'] = {'', '1995–2005'},
},
['The History of al-Tabari'] = {
['1'] = {'Rosenthal', '1989'},
['2'] = {'Brinner', '1986'},
['3'] = {'Brinner', '1991'},
['4'] = {'Perlmann', '1987'},
['5'] = {'Bosworth', '1999'},
['6'] = {'WattMcDonald', '1989'},
['7'] = {'McDonald', '1987'},
['8'] = {'Fishbein', '1997'},
['9'] = {'Poonawala', '1990'},
['10'] = {'Donner', '1993'},
['11'] = {'Blankinship', '1993'},
['12'] = {'Friedmann', '1992'},
['13'] = {'Juynboll', '1989'},
['14'] = {'Smith', '1994'},
['15'] = {'Humphreys', '1990'},
['16'] = {'Brockett', '1997'},
['17'] = {'Hawting', '1996'},
['18'] = {'Morony', '1987'},
['19'] = {'Howard', '1990'},
['20'] = {'Hawting', '1989'},
['21'] = {'Fishbein', '1990'},
['22'] = {'Rowson', '1989'},
['23'] = {'Hinds', '1990'},
['24'] = {'Powers', '1989'},
['25'] = {'Blankinship', '1989'},
['26'] = {'Hillenbrand', '1989'},
['27'] = {'Williams', '1985'},
['28'] = {'McAuliffe', '1995'},
['29'] = {'Kennedy', '1990'},
['30'] = {'Bosworth', '1989'},
['31'] = {'Fishbein', '1992'},
['32'] = {'Bosworth', '1987'},
['33'] = {'Bosworth', '1991'},
['34'] = {'Kraemer', '1989'},
['35'] = {'Saliba', '1985'},
['36'] = {'Waines', '1992'},
['37'] = {'Fields', '1987'},
['38'] = {'Rosenthal', '1985'},
['39'] = {'Landau-Tasseron', '1998'},
['40'] = {'Popovkin', '2007'},
['default'] = {'Yarshater', '1985–2007'},
},
}
--[[--------------------------< W R A P P E R _ T E M P L A T E S >--------------------------------------------
A list of wrapper templates and their redirects – spelling and capitalization is important; first character is
always uppercase. Each wrapper template gets its value from a k/v pair in the wrapper_template_defaults table.
article reader queries this table to see if template_name is a wrapper template
]]
local wrapper_templates = { -- keys are names of wrapper templates and their redirects
['Americana'] = wrapper_template_defaults['Americana'], -- canonical name; this template calls Cite Americana
['Catholic Encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['1913Catholic'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Catholic'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Catholic encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CatholicEncyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CE13'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CE1913'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite Americana'] = wrapper_template_defaults['Americana'], -- canonical name
['Cite Catholic Encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CathEncy'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite Catholic Encyclopædia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite CE1913'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite EB1911'] = wrapper_template_defaults['Cite EB1911'], -- canonical name
['1911EB'] = wrapper_template_defaults['Cite EB1911'], -- redirects
['EB1911 cite'] = wrapper_template_defaults['Cite EB1911'],
['Wikisource1911Enc Citation'] = wrapper_template_defaults['Cite EB1911'],
['Wikisource1911Enc citation'] = wrapper_template_defaults['Cite EB1911'],
['Cite EB9'] = wrapper_template_defaults_vol['Cite EB9'], -- canonical
['Eb9'] = wrapper_template_defaults_vol['Cite EB9'],
['Cite ODNB'] = wrapper_template_defaults['ODNB'], -- canonical
['Cite odnb'] = wrapper_template_defaults['ODNB'],
['DNBweb'] = wrapper_template_defaults['ODNB'],
['OBDNweb'] = wrapper_template_defaults['ODNB'],
['ODNB'] = wrapper_template_defaults['ODNB'],
['ODNBref'] = wrapper_template_defaults['ODNB'],
['ODNBweb'] = wrapper_template_defaults['ODNB'],
['EB1911'] = wrapper_template_defaults['EB1911'], -- canonical name; this template calls Cite EB1911
['1911'] = wrapper_template_defaults['EB1911'], -- redirects
['1911s'] = wrapper_template_defaults['EB1911'],
['Britannica 1911'] = wrapper_template_defaults['EB1911'],
['Encyclopedia Britannica 1911'] = wrapper_template_defaults['EB1911'],
['Encyclopædia Britannica 1911'] = wrapper_template_defaults['EB1911'],
['EB9'] = wrapper_template_defaults_vol['Cite EB9'], -- canonical; this template calls Cite EB9
['Encyclopaedia of Islam, New Edition'] = wrapper_template_defaults_vol['Encyclopaedia of Islam, New Edition'], -- canonical
['EI2'] = wrapper_template_defaults_vol['Encyclopaedia of Islam, New Edition'],
['Encyclopaedia of Islam, THREE'] = wrapper_template_defaults['EI3'], -- canonical
['EI3'] = wrapper_template_defaults['EI3'],
['New Cambridge Medieval History'] = wrapper_template_defaults_vol['New Cambridge Medieval History'], -- canonical
['The History of al-Tabari'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- canonical
['The History of Al-Tabari'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- redirects
['The History of al-Ṭabarī'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- redirects
}
--[[--------------------------< T E M P L A T E _ N A M E S >--------------------------------------------------
This table holds the names of templates and the names of their redirects. Template names must be written exactly
as they are named at their templatespace page. This same also applies to redirects.
The indexes in this table are not critical but should be short and concise.
]]
local template_names = {
['ADB'] = {'Allgemeine Deutsche Biographie', 'Cite ADB'},
['Butt_Stations'] = {'Butt-Stations', 'Butt-stations'},
['Cam_Hist_Iran'] = {'Cambridge History of Iran', 'The Cambridge History of Iran'},
['DNB'] = {'Cite DNB', 'DNB', 'DNB Cite', 'Cite DNBSupp', 'DNBSupp', 'Cite DNB12', 'Cite DNBIE', 'DNB12', 'DNBIE', 'DNBfirst'},
['ME-ref'] = {'ME-ref', 'Me-ref'},
['ODB'] = {'ODB', 'Oxford Dictionary of Byzantium'},
['ODLA'] = {'ODLA', 'Oxford Dictionary of Late Antiquity'},
['NDB'] = {'Cite NDB', 'NDB'},
['Iranica'] = {'Encyclopædia Iranica Online', 'Encyclopædia Iranica', 'Encyclopaedia Iranica', 'Cite Encyclopædia Iranica Online'},
}
--[[--------------------------< S P E C I A L _ P A T T E R N S >----------------------------------------------
Lua patterns. These are scanned sequentially which costs time and processing far and above the time and processing
needed to index into whitelist{}. Do not create a pattern here if a normal whitelist entry or entries can be created.
]]
local special_patterns = {
'CITEREFACAD%u%u%u?%u?%d+%u%u?', -- {{Acad}} ID appears to be 2-4 letters, then 3 numbers, then 1-2 letters
'CITEREFAHD%d+', -- {{Cite AHD}}
'CITEREFHistoric_England%d+', -- {{National Heritage List for England}} & {{PastScape}}
'CITEREFHistoric_Environment_Scotland%u%u%u?%u?%d', -- {{Historic Environment Scotland}} %u can be BTL, GLD, HMPA, LB, SM
'CITEREFQHR%d+', -- {{Cite QHR}}
'CITEREF[%d%a_%pöüäß→]+_at_Bach_Digital', -- {{BDh}}
'CITEREF[BR]GBl_[12]%d%d%d%-?I?I?%/%d+', -- {{Cite Austrian gazette}}
'CITEREFStGBl_[12]%d%d%d%/%d+', -- {{Cite Austrian gazette}}
'CITEREFGBlÖ_[12]%d%d%d%/%d+', -- {{Cite Austrian gazette}}
}
--[[--------------------------< D N B _ S P E C I A L _ P A T T E R N S >--------------------------------------
Lua patterns. Note at special_patterns applies. These for the DNB templates only; these will be tried only when
there is a DNB template in the article.
Pretty much any author name during the period 1885–1901 inclusive, and 1912.
The DNBIE was published in 1903, and Template:DNBIE says that its use is deprecated, but we do not fight that battle here.
]]
local DNB_special_patterns = {
'CITEREF%a[%a%-_\']*188[5-9]', -- 1885–1889
'CITEREF%a[%a%-_\']*189%d', -- 1890–1899
'CITEREF%a[%a%-_\']*190[0-1]', -- 1900–1901
'CITEREF%a[%a%-_\']*1903', -- 1903 IE
'CITEREF%a[%a%-_\']*1912', -- 1912 supplement
}
--[[--------------------------< W H I T E L I S T >------------------------------------------------------------
This is a list of anchor IDs known to be associated with specific wrapper templates. The anchor ID serves as an
index into the table. The assigned value is another table that lists the associated template and any redirects.
Except for year disambiguators, anchor IDs must have the same form as the anchor creator makes; must be the
anchor-encoded form. Remove the year disambiguator.
Template names must be written exactly as they are named at their templatespace page. This same also applies to
redirects. Module:Footnotes reads the template names left to right so most-commonly-used template or redirect name
should appear first. When there are more than one name and when those templates have various anchor IDs the template
namelist should be added to the template_names{} table.
Note that references to Template:EB1911 are listed under "E" in the alphabetical list below to keep them organized.
]]
local whitelist = {
----------< # >----------
['CITEREF2013_Statistical_Yearbook_of_the_Republic_of_Croatia'] = {'Croatia Yearbook 2013'},
----------< A >----------
['CITEREFAGA_1884–1897'] = {'Schubert\'s compositions (references)'},
['CITEREFATOC2009'] = {'ATOCConnectingCommunitiesReportS10'},
['CITEREFAbaevBailey1985'] = template_names['Iranica'],
['CITEREFAbbas1988'] = template_names['Iranica'],
['CITEREFAbbas1989'] = template_names['Iranica'],
['CITEREFAbramowitzStegun1983'] = {'Abramowitz Stegun ref'},
['CITEREFActa_Lipsiensium1723'] = {'Bach\'s compositions (sources)'},
['CITEREFAdamsFranzosa2009'] = {'Adams Franzosa Introduction to Topology Pure and Applied'},
['CITEREFAdaschErnstKeim1978'] = {'Adasch Topological Vector Spaces'},
['CITEREFAffleck1978'] = {'Affleck-On Track'},
['CITEREFAhlgrimm1969'] = {'Bach\'s compositions (sources)'},
['CITEREFAhmadiNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFAhrons1927'] = {'Book-Ahrons-British Steam Railway Locomotive'},
['CITEREFAl-Kindi1912'] = {'The Governors and Judges of Egypt'},
['CITEREFAlbert_Schumann1886'] = {'Cite ADB'},
['CITEREFAlden1916'] = {'Shakespeare sonnets bibliography'},
['CITEREFAldrich1969'] = {'Aldrich-LocosGER7'},
['CITEREFAleksidze2018'] = template_names['ODLA'],
['CITEREFAlexiou2010'] = {'Cite flatiron'},
['CITEREFAlgar1983'] = template_names['Iranica'],
['CITEREFAlgar1989'] = template_names['Iranica'],
['CITEREFAlgar1990'] = template_names['Iranica'],
['CITEREFAlgar2003'] = template_names['Iranica'],
['CITEREFAlizadeh1990'] = template_names['Iranica'],
['CITEREFAllamaniPanagiotopoulou1978'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFAllcockDaviesle_FlemingMaskelyne1968'] = {'RCTS-LocosGWR-1'},
['CITEREFAllenBoddyBrownFry1970'] = {'RCTS-LocosLNER-8A'},
['CITEREFAllenBoddyBrownFry1971'] = {'RCTS-LocosLNER-8B'},
['CITEREFAllenBoddyBrownFry1983'] = {'RCTS-LocosLNER-8A'},
['CITEREFAmanat1998'] = template_names['Iranica'],
['CITEREFAmanat1999'] = template_names['Iranica'],
['CITEREFAmbartsumian2014'] = template_names['Iranica'],
['CITEREFAmerican_Railway_Association1922'] = {'1922 Locomotive Cyclopedia'},
['CITEREFAnderson1952'] = {'Naval Wars in the Levant 1559–1853'},
['CITEREFAndo2000'] = template_names['Iranica'],
['CITEREFAngelov2018'] = template_names['ODLA'],
['CITEREFAnwārEIr1985'] = template_names['Iranica'],
['CITEREFArkhangel'skiiPonomarev1984'] = {'Arkhangel\'skii Ponomarev Fundamentals of General Topology Problems and Exercises'},
['CITEREFArrey_von_Dommer1875'] = {'Cite ADB'},
['CITEREFAshraf2006'] = template_names['Iranica'],
['CITEREFAslanianBerberian2009'] = template_names['Iranica'],
['CITEREFAsmus1966'] = template_names['NDB'],
['CITEREFAsmussen1985'] = template_names['Iranica'],
['CITEREFAspreas1929'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFAtkins2007'] = {'Shakespeare sonnets bibliography'},
['CITEREFAube2011'] = template_names['Iranica'],
['CITEREFAudiKondevWangHuang2017'] = {'NUBASE2016'},
['CITEREFAvdoyan2018'] = template_names['ODLA'],
['CITEREFAwdry1990'] = {'Awdry-RailCo', 'Carnarvonshire Railway'},
['CITEREFAzarnoosh2021'] = template_names['Iranica'],
['CITEREFRamelli2018'] = {'Oxford Dictionary of Late Antiquity'},['CITEREFA_History_of_the_Crusades'] = {'Setton-A History of the Crusades'},
----------< B >----------
['CITEREFBabinger1962'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBabinger1978'] = {'Mehmed the Conqueror and His Time'},
['CITEREFBabinger1992'] = {'Mehmed the Conqueror and His Time'},
['CITEREFBachAgricola1754'] = {'Bach\'s compositions (sources)'},
['CITEREFBadura-SkodaBranscombe2008'] = {'Schubert\'s compositions (references)'},
['CITEREFBahramianHirtensteinGholami2013'] = {'Encyclopaedia Islamica'},
['CITEREFBalcer1990'] = template_names['Iranica'],
['CITEREFBaldwin1969'] = {'Setton-A History of the Crusades'},
['CITEREFBaldwin1985'] = {'Setton-A History of the Crusades'},
['CITEREFBaldwinKazhdan1991'] = template_names['ODB'],
['CITEREFBaldwinTalbot1991'] = template_names['ODB'],
['CITEREFBaltzer1916'] = {'Baltzer-Kolonialbahnen'},
['CITEREFBanach1932'] = {'Banach Théorie des Opérations Linéaires'},
['CITEREFBandy2021'] = template_names['Iranica'],
['CITEREFBartusis1991'] = template_names['ODB'],
['CITEREFBaxter1971'] = {'Baxter-BritishLocoCat1'},
['CITEREFBaxter1977'] = {'Baxter-BritishLocoCat1'},
['CITEREFBaxter1978'] = {'Baxter-BritishLocoCat2A'},
['CITEREFBaxter1979'] = {'Baxter-BritishLocoCat2B'},
['CITEREFBaxter1982'] = {'Baxter-BritishLocoCat3A', 'Baxter-BritishLocoCat3B'},
['CITEREFBaxter1984'] = {'Baxter-BritishLocoCat4'},
['CITEREFBaxter1986'] = {'Baxter-BritishLocoCat5A'},
['CITEREFBaxter1988'] = {'Baxter-BritishLocoCat5B'},
['CITEREFBaxter2012'] = {'Baxter-BritishLocoCat6'},
['CITEREFBeattie1986'] = template_names['Iranica'],
['CITEREFBeißwenger1991'] = {'Bach\'s compositions (sources)'},
['CITEREFBek2001'] = {'Cite Grove'},
['CITEREFBelke1996'] = {'Tabula Imperii Byzantini'},
['CITEREFBelkeMersisch1990'] = {'Tabula Imperii Byzantini'},
['CITEREFBelkeRestle1984'] = {'Tabula Imperii Byzantini'},
['CITEREFBellini2008'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBernardini2003'] = template_names['Iranica'],
['CITEREFBernhard_von_Poten1889'] = template_names['ADB'],
['CITEREFBernhard_von_Poten1898'] = template_names['ADB'],
['CITEREFBernjian2008'] = {'Encyclopaedia Islamica'},
['CITEREFBezilla1980'] = {'Bezilla-PRR-Electric-Traction'},
['CITEREFBianquis1998'] = {'The Cambridge History of Egypt', 'Cambridge History of Egypt'},
['CITEREFBickerman1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBierstedt1988'] = {'Bierstedt An Introduction to Locally Convex Inductive Limits'},
['CITEREFBiran2009'] = template_names['Iranica'],
['CITEREFBirken1976'] = {'Die Provinzen des Osmanischen Reiches'},
['CITEREFBivar1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBivar2003'] = template_names['Iranica'],
['CITEREFBlair2002'] = template_names['Iranica'],
['CITEREFBlair2021'] = template_names['Iranica'],
['CITEREFBlake1966'] = {'DisraeliRef'},
['CITEREFBlanken2019'] = {'Bach\'s compositions (sources)'},
['CITEREFBlankinship1994'] = {'The End of the Jihâd State', 'The End of the Jihad State'},
['CITEREFBlautSchulze2008'] = {'Bach\'s compositions (sources)'},
['CITEREFBloom2007'] = {'Cite Routledge Broadway', 'Cite Broadway Routledge', 'Cite Routledge Guide to Broadway', 'Routledge Guide to Broadway'},
['CITEREFBock1978'] = {'Audie-bock-directors'},
['CITEREFBoddyBrownFryHennigan1968'] = {'RCTS-LocosLNER-4'},
['CITEREFBoddyBrownFryHennigan1975'] = {'RCTS-LocosLNER-2B'},
['CITEREFBoddyBrownFryHennigan1977'] = {'RCTS-LocosLNER-9A', 'RCTS-LocosLNER-9B'},
['CITEREFBoddyBrownFryHennigan1979'] = {'RCTS-LocosLNER-3A'},
['CITEREFBoddyBrownHenniganHoole1984'] = {'RCTS-LocosLNER-6C'},
['CITEREFBoddyBrownHenniganNeve1981'] = {'RCTS-LocosLNER-3B'},
['CITEREFBoddyBrownNeveYeadon1983'] = {'RCTS-LocosLNER-6B'},
['CITEREFBoddyFryHenniganHoole1990'] = {'RCTS-LocosLNER-10B'},
['CITEREFBoddyFryHenniganProud1963'] = {'RCTS-LocosLNER-1'},
['CITEREFBoddyNeveTeeYeadon1982'] = {'RCTS-LocosLNER-6A'},
['CITEREFBoddyNeveYeadon1973'] = {'RCTS-LocosLNER-2A'},
['CITEREFBody1989'] = {'Body-Railways-Vol2'},
['CITEREFBon1969'] = {'La Morée franque'},
['CITEREFBonebakker1997'] = template_names['Iranica'],
['CITEREFBonner2010'] = {'New Cambridge History of Islam'},
['CITEREFBonnett2005'] = {'Bonnett Practical Rail Engineering'},
['CITEREFBonporti1712'] = {'Bach\'s compositions (sources)'},
['CITEREFBooth2000'] = {'Shakespeare sonnets bibliography'},
['CITEREFBorsari1964'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBossert1914'] = {'Schaff-Herzog'},
['CITEREFBosworth1968'] = template_names['Cam_Hist_Iran'],
['CITEREFBosworth1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBosworth1983'] = template_names['Iranica'],
['CITEREFBosworth1984'] = template_names['Iranica'],
['CITEREFBosworth1987'] = template_names['Iranica'],
['CITEREFBosworth1988'] = template_names['Iranica'],
['CITEREFBosworth1989'] = template_names['Iranica'],
['CITEREFBosworth1994'] = template_names['Iranica'],
['CITEREFBosworth1995'] = template_names['Iranica'],
['CITEREFBosworth1997'] = template_names['Iranica'],
['CITEREFBosworth1998'] = template_names['Iranica'],
['CITEREFBosworth2000'] = template_names['Iranica'],
['CITEREFBosworth2001'] = template_names['Iranica'],
['CITEREFBosworth2002'] = template_names['Iranica'],
['CITEREFBosworth2003'] = template_names['Iranica'],
['CITEREFBosworth2008'] = template_names['Iranica'],
['CITEREFBosworth2009'] = template_names['Iranica'],
['CITEREFBosworth2010'] = template_names['Iranica'],
['CITEREFBosworth2011'] = template_names['Iranica'],
['CITEREFBosworthCrane1984'] = template_names['Iranica'],
['CITEREFBottoMitchell2002'] = {'Cite ATT Broadway', 'Cite At This Theatre Broadway', 'Cite Broadway At This Theatre', 'Cite Broadway ATT'},
['CITEREFBourbaki1987'] = {'Bourbaki Topological Vector Spaces'},
['CITEREFBourbaki1989'] = {'Bourbaki General Topology Part I Chapters 1-4', 'Bourbaki General Topology Part II Chapters 5-10', 'Bourbaki Algebra I Chapters 1-3 Springer'},
['CITEREFBourbaki1994'] = {'Bourbaki EHM'},
['CITEREFBowen1928'] = {'The Life and Times of Ali ibn Isa'},
['CITEREFBowmanCameronGarnsey2005'] = {'Cambridge Ancient History'},
['CITEREFBoyce1983'] = template_names['Iranica'],
['CITEREFBoyce1986'] = template_names['Iranica'],
['CITEREFBoyce1989'] = template_names['Iranica'],
['CITEREFBoyce2000'] = template_names['Iranica'],
['CITEREFBoyce2009'] = template_names['Iranica'],
['CITEREFBoyd1970'] = {'Boyd-MidWales'},
['CITEREFBoyd1975'] = {'Boyd-FR1'},
['CITEREFBoyd1985'] = {'Boyd-NCaerns2Penrhyn'},
['CITEREFBoyd1986'] = {'Boyd-NCaerns3Dinorwic'},
['CITEREFBoyd1988'] = {'Boyd-SCaerns1'},
['CITEREFBoyd1989'] = {'Boyd-SCaerns2'},
['CITEREFBoyd1990'] = {'Boyd-NCaerns1'},
['CITEREFBradshaw1968'] = {'Bradshaw-1910April'},
['CITEREFBradshaw1985'] = {'Bradshaw-1922July'},
['CITEREFBradshaw2011'] = {'Bradshaw-1895December'},
['CITEREFBradshaw2012'] = {'Bradshaw-1850March'},
['CITEREFBrand1968'] = {'Byzantium Confronts the West'},
['CITEREFBrand1991'] = {'DBI', 'ODB', 'Oxford Dictionary of Byzantium'},
['CITEREFBray2010'] = {'Bray-SDJR'},
['CITEREFBrett2010'] = {'New Cambridge History of Islam'},
['CITEREFBriant1985'] = template_names['Iranica'],
['CITEREFBrosius2000'] = template_names['Iranica'],
['CITEREFBrown2000'] = template_names['Iranica'],
['CITEREFBrown2008'] = {'The Cambridge History of the Byzantine Empire'},
['CITEREFBrunner1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBrunner1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBrunner1984'] = template_names['Iranica'],
['CITEREFBrunner1986'] = template_names['Iranica'],
['CITEREFBryan1886'] = {'Bryan (3rd edition)'},
['CITEREFBryan1889'] = {'Bryan (3rd edition)'},
['CITEREFBuhle1909'] = {'Bach\'s compositions (sources)'},
['CITEREFBulliet1984'] = template_names['Iranica'],
['CITEREFBulookbashiNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFBunbury1857'] = {'DGRG'},
['CITEREFBurant1987'] = {'Cite DCB'},
['CITEREFBurch1911'] = {'Burch Electric Traction'},
['CITEREFBurke1866'] = {'O\'Donnell family tree'},
['CITEREFBurn1985'] = template_names['Cam_Hist_Iran'],
['CITEREFBurrowsWallace1999'] = {'Cite gotham'},
['CITEREFBury1911'] = {'The Imperial Administrative System of the Ninth Century'},
['CITEREFBusse1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBusse1982'] = template_names['Iranica'],
['CITEREFButcherNicholson2018'] = template_names['ODLA'],
['CITEREFButt1995'] = template_names['Butt_Stations'],
['CITEREFBöwering1995'] = template_names['Iranica'],
['CITEREFBürgelMottahedeh1988'] = template_names['Iranica'],
----------< C >----------
['CITEREFCIC1983'] = {'CIC1983bib'},
['CITEREFCalifornia1988'] = {'CA-Rail Passenger Development Plan-1988'},
['CITEREFCalmard1988'] = template_names['Iranica'],
['CITEREFCalmard1999'] = template_names['Iranica'],
['CITEREFCaltrans1984'] = {'Countrystudy'},
['CITEREFCameronWard-PerkinsWhitby2000'] = {'Cambridge Ancient History'},
['CITEREFCanepa2018'] = template_names['ODLA'],
['CITEREFCanny2008'] = {'O\'Donnell family tree'},
['CITEREFCappelCutlerKazhdan1991'] = template_names['ODB'],
['CITEREFCarl_von_Prantl1879'] = {'Cite ADB'},
['CITEREFCarlson2010'] = {'Dlmf'},
['CITEREFCaro1974'] = {'Cite Power Broker'},
['CITEREFCarpenter1977'] = template_names['ME-ref'],
['CITEREFCarpenter1981'] = template_names['ME-ref'],
['CITEREFCarra_de_VauxHodgson1965'] = {'EI2'},
['CITEREFCarter2006'] = {'Carter-RailwaysMotivePowerArgentina'},
['CITEREFCasserley1968'] = {'Casserley-joint'},
['CITEREFCasserleyJohnston1966'] = {'Casserley-LocoGrouping3'},
['CITEREFCasserleyJohnston1974'] = {'Casserley-LocoGrouping3', 'Casserley-LocoGrouping2', '0-7110-0554-0'},
['CITEREFCasway1984'] = {'O\'Donnell family tree'},
['CITEREFCavanna_Ciappina2001'] = {'DBI'},
['CITEREFCawley2001'] = {'Medieval Lands by Charles Cawley', 'MLCC'},
['CITEREFCawley2001'] = {'Medieval Lands by Charles Cawley'},
['CITEREFCawley2010'] = {'MLCC'},
['CITEREFCawley2011'] = {'MLCC'},
['CITEREFChaléardChanson-JabeurBéranger2006'] = {'Chaléard-Le cdf en Afrique'},
['CITEREFChambers1728'] = {'Cyclopaedia 1728'},
['CITEREFChasiotis1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFChaumont1985'] = template_names['Iranica'],
['CITEREFChaumont1986'] = template_names['Iranica'],
['CITEREFChaumont1987'] = template_names['Iranica'],
['CITEREFChaumont1990'] = template_names['Iranica'],
['CITEREFChaumontSchippmann1988'] = template_names['Iranica'],
['CITEREFCheyneBlack1899'] = {'Biblica', 'Cite Biblica'},
['CITEREFCheyneBlack1899–1903'] = {'Cite Biblica'},
['CITEREFCheyneBlack1901'] = {'Cite Biblica'},
['CITEREFCheyneBlack1902'] = {'Cite Biblica'},
['CITEREFCheyneBlack1903'] = {'Cite Biblica'},
['CITEREFChisholm1922'] = {'EB1922', 'Cite EB1922'},
['CITEREFChittick1997'] = template_names['Iranica'],
['CITEREFChkeidze2001'] = template_names['Iranica'],
['CITEREFChoniates1984'] = {'O City of Byzantium'},
['CITEREFChrista_Jost1999'] = template_names['NDB'],
['CITEREFChung1994'] = {'Country study'},
['CITEREFChurchmanHurst2001'] = {'Churchman & Hurst Railways of New Zealand'},
['CITEREFChurchman_&_Hurst2001'] = {'Churchman & Hurst Railways of New Zealand'},
['CITEREFChurella2013'] = {'Churella-PRR-1'},
['CITEREFClementsMcMahon2008'] = {'ClementsMcMahon-GSR Locomotives'},
['CITEREFClinker1978'] = {'Clinker-Stations'},
['CITEREFClinker1988'] = {'Clinker-Stations'},
['CITEREFCoates1990'] = {'Coates-Reading'},
['CITEREFColbyWilliams1916'] = {'New International Encyclopedia', 'NIE'},
['CITEREFColledgeWarlow2006'] = {'Colledge', 'Cite Colledge2006'},
['CITEREFColledgeWarlow2010'] = {'Cite Colledge2010'},
['CITEREFCollins2016'] = {'Cite Collins 2016'},
['CITEREFConolly1998'] = {'IanAllan-PreGroup-Atlas1998'},
['CITEREFConway1990'] = {'Conway A Course in Functional Analysis'},
['CITEREFCosentino2008'] = {'DBI'},
['CITEREFCoulthard-Clark2002'] = {'Australian Dictionary of Biography'},
['CITEREFCousin1910'] = {'A Short Biographical Dictionary of English Literature', 'Cite SBDEL'},
['CITEREFCox1967'] = {'Cox-Upper Darby'},
['CITEREFCox2011'] = {'Cox-Dixie'},
['CITEREFCrevier1993'] = {'Crevier 1993'},
['CITEREFCrockett2007'] = {'Australian Dictionary of Biography'},
['CITEREFCroke2018'] = template_names['ODLA'],
['CITEREFCrone1980'] = {'Slaves on Horses'},
['CITEREFCronin2011'] = template_names['Iranica'],
['CITEREFCroughtonKidnerYoung1982'] = {'Croughton-PrivateStations'},
['CITEREFCruickshanks1970'] = {'HistoryofParliament'},
['CITEREFCudahy2002'] = {'Cudahy-Hudson'},
['CITEREFCudahy2003'] = {'Cudahy-Subways'},
['CITEREFCurta2006'] = {'Southeastern Europe in the Middle Ages, 500–1250'},
----------< D >----------
['CITEREFDBI'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFDZS2015'] = {'Croatia Yearbook 2015'},
['CITEREFDadelsen1957'] = {'Bach\'s compositions (sources)'},
['CITEREFDaftary1990'] = {'Daftary-The Ismailis'},
['CITEREFDaftary2003'] = template_names['Iranica'],
['CITEREFDaftary2007'] = {'Daftary-The Ismailis'},
['CITEREFDaftary2015'] = template_names['Iranica'],
['CITEREFDaiber1988'] = template_names['Iranica'],
['CITEREFDandamayevShahbaziLecoq1986'] = template_names['Iranica'],
['CITEREFDaniel2000'] = template_names['Iranica'],
['CITEREFDaniel2010'] = {'New Cambridge History of Islam'},
['CITEREFDanielsDench1963'] = {'Daniels-NoMore'},
['CITEREFDanielsDench1973'] = {'Daniels-NoMore'},
['CITEREFDanner1975'] = template_names['Cam_Hist_Iran'],
['CITEREFDarleyCanepa2018'] = {'Oxford Dictionary of Late Antiquity'},
['CITEREFDaryaee2009'] = template_names['Iranica'],
['CITEREFDaryaee2018'] = template_names['ODLA'],
['CITEREFDaryaeeCanepa2018'] = template_names['ODLA'],
['CITEREFDavid1961'] = {'Bach\'s compositions (sources)'},
['CITEREFDavidson2010'] = {'HistoryofParliament'},
['CITEREFDavidsonThrush2010'] = {'HistoryofParliament'},
['CITEREFDavies1996'] = {'Davies-PLMLocoList'},
['CITEREFDavies1997'] = {'Davies-NordLocoList'},
['CITEREFDavies2001'] = {'Davies-EstLocoList3', 'Davies-ÉtatLocoList'},
['CITEREFDavies2003'] = {'Davies-SNCFLocoList'},
['CITEREFDaviesFirthLuckingThomas1966'] = {'RCTS-LocosGWR-10'},
['CITEREFDavud2018'] = {'Encyclopaedia Islamica'},
['CITEREFDavudNazerian2008'] = {'Encyclopaedia Islamica'},
['CITEREFDe_Negri1997'] = {'DBI'},
['CITEREFDemircan2010'] = {'TDV Encyclopedia of Islam'},
['CITEREFDeutsch1951'] = {'Schubert\'s compositions (references)'},
['CITEREFDeutsch1978'] = {'Schubert\'s compositions (references)'},
['CITEREFDeutsche_Autos,_Band_2,2001'] = {'Deutsche Autos-2'},
['CITEREFDeutsche_Autos,_Band_3,2001'] = {'Deutsche Autos-3'},
['CITEREFDeutsche_Autos,_Band_4,2001'] = {'Deutsche Autos-4'},
['CITEREFDeutsche_Autos,_Band_5,2001'] = {'Deutsche Autos-5'},
['CITEREFDeutsche_Autos,_Band_6,2001'] = {'Deutsche Autos-6'},
['CITEREFDewick2005'] = {'Dewick-Atlas'},
['CITEREFDiamonstein-Spielvogel2011'] = {'Cite landmarks'},
['CITEREFDickens2018'] = template_names['ODLA'],
['CITEREFDirksen1998'] = {'Bach\'s compositions (sources)'},
['CITEREFDirksen2010'] = {'Bach\'s compositions (sources)'},
['CITEREFDirksen2016'] = {'Bach\'s compositions (sources)'},
['CITEREFDixmier1984'] = {'Dixmier General Topology'},
['CITEREFDoerfer1989'] = template_names['Iranica'],
['CITEREFDoganis1930'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFDoleckiMynard2016'] = {'Dolecki Mynard Convergence Foundations Of Topology'},
['CITEREFDolkart1998'] = {'Cite morningside'},
['CITEREFDonner1995'] = template_names['Iranica'],
['CITEREFDonohue2003'] = {'The Buwayhid Dynasty in Iraq'},
['CITEREFDorin1972'] = {'Dorin-North Western'},
['CITEREFDow1962'] = {'Dow-GC2'},
['CITEREFDow1965'] = {'Dow-GC3'},
['CITEREFDow1985'] = {'Dow-GC1'},
['CITEREFDowney2007'] = {'Downey-Chicago'},
['CITEREFDrechsler2005'] = template_names['Iranica'],
['CITEREFDrummond1964'] = {'HistoryofParliament'},
['CITEREFDrury1985'] = {'Drury Historical Guide 1985'},
['CITEREFDrury1993'] = {'Drury-North American Steam'},
['CITEREFDuchesne-Guillemin1994'] = template_names['Iranica'],
['CITEREFDugundji1966'] = {'Dugundji Topology'},
['CITEREFDuke1995'] = {'Duke-Santa Fe-1'},
['CITEREFDukeKeilty1990'] = {'Duke-RDC'},
['CITEREFDumbarton_Oaks_Hagiography_Database'] = {'Dumbarton Oaks Hagiography Database'},
['CITEREFDunbar1969'] = {'Dunbar-Railroads'},
['CITEREFDuncan-Jones2010'] = {'Shakespeare sonnets bibliography'},
['CITEREFDunlop1895'] = {'O\'Donnell family tree'},
['CITEREFDunlop1985'] = template_names['Iranica'],
['CITEREFDunn2013'] = {'Dunn-Comeng-5'},
['CITEREFDurand-Guédy2008'] = template_names['Iranica'],
['CITEREFDurand-Guédy2010'] = template_names['Iranica'],
['CITEREFDurand-Guédy2013'] = {'Encyclopaedia Islamica'},
['CITEREFDurham1998'] = {'California\'s Geographic Names'},
['CITEREFDurrant1972'] = {'Durrant-Steam Locos Eastern Europe'},
['CITEREFDurrant1981'] = {'Durrant-Garratt-Rev'},
['CITEREFDurrantLewisJorgensen1981'] = {'Durrant-SteamAfrica'},
['CITEREFDömlingKohlhase1971'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1952'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1954'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1987'] = {'Bach\'s compositions (sources)'},
['CITEREFDürrJones2006'] = {'Bach\'s compositions (sources)'},
['CITEREFDürrKobayashi1998'] = {'Bach\'s compositions (sources)'},
['CITEREFde_Blois2000'] = template_names['Iranica'],
['CITEREFde_Planhol1987'] = template_names['Iranica'],
['CITEREFde_Planhol1988'] = template_names['Iranica'],
----------< E >----------
['CITEREFEIr.1994'] = template_names['Iranica'],
['CITEREFEarle2018'] = {'Gymnosperm Database'},
['CITEREFEbata2019'] = {'BDh'},
['CITEREFEbata2020'] = {'BDh'},
['CITEREFEbrahimKhodaverdian2018'] = {'Encyclopaedia Islamica'},
['CITEREFEdwards1995'] = {'Edwards Functional Analysis Theory and Applications'},
['CITEREFEichberg1976'] = {'Bach\'s compositions (sources)'},
['CITEREFEilers1983'] = template_names ['Cam_Hist_Iran'],
['CITEREFEkbal1991'] = template_names['Iranica'],
['CITEREFEl-Hibri2010'] = {'New Cambridge History of Islam'},
['CITEREFEldredgeHorenstein2014'] = {'Cite concrete'},
['CITEREFElsholz1982'] = {'Schubert\'s compositions (references)'},
['CITEREFElwell-Sutton1984'] = template_names['Iranica'],
['CITEREFEppstein1966'] = {'Bach\'s compositions (sources)'},
['CITEREFEppstein1982'] = {'Bach\'s compositions (sources)'},
['CITEREFEquasis'] = {'Csr', 'Cite ship register'},
['CITEREFEuDaly2009'] = {'Complete Book of North American Railroading'},
['CITEREFEuDalySchaferJessupBoyd2009'] = {'Complete Book of North American Railroading'},
----------< F >----------
['CITEREFFacella2021'] = template_names['Iranica'],
['CITEREFFang1943'] = {'Cite ECCP'},
['CITEREFFarinella2001'] = {'DBI'},
['CITEREFFatehi-NezhadAzarnooshNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFFatehi-nezhadRahimi2008'] = {'Encyclopaedia Islamica'},
['CITEREFFeder1958'] = {'Bach\'s compositions (sources)'},
['CITEREFFederal_Writers'_Project1939'] = {'Cite fednyc'},
['CITEREFFelixMadelung1995'] = template_names['Iranica'],
['CITEREFFernandez1983'] = {'Fernandez1983'},
['CITEREFFesharaki2015'] = {'Encyclopaedia Islamica'},
['CITEREFFiaccadori1991'] = template_names['ODB'],
['CITEREFFikratUmar2008'] = template_names['Iranica'],
['CITEREFFine1991'] = {'The Early Medieval Balkans'},
['CITEREFFine1994'] = {'The Late Medieval Balkans'},
['CITEREFFletcher,_Great_Tank_Scandal'] = {'Book-Fletcher-Great Tank Scandal'},
['CITEREFFletcher,_Universal_Tank'] = {'Book-Fletcher-Universal Tank'},
['CITEREFFloor1992'] = template_names['Iranica'],
['CITEREFFloor2005'] = template_names['Iranica'],
['CITEREFFlora_of_North_America'] = {'EFloras'},
['CITEREFFlora_of_North_America2009'] = {'EFloras'},
['CITEREFFluckMarshallWilson1996'] = {'FluMarWil-LocRailCR'},
['CITEREFFonstad1991'] = template_names['ME-ref'],
['CITEREFForkelTerry1920'] = {'Bach\'s compositions (sources)'},
['CITEREFFornaçon,_Siegfried1957'] = template_names['NDB'],
['CITEREFForrestal1999'] = {'Forrestal-Wineries'},
['CITEREFForster1990'] = {'Cite DCB'},
['CITEREFFoss1991'] = template_names['ODB'],
['CITEREFFoster1971'] = template_names['ME-ref'],
['CITEREFFoster1996'] = {'Foster-Field Guide'},
['CITEREFFrailey2010'] = {'Frailey-Twilight'},
['CITEREFFranke1994'] = {'Cite Cambridge History of China'},
['CITEREFFranz_Schnorr_von_Carolsfeld1883'] = {'Cite ADB'},
['CITEREFFriedrich_Wilhelm_Bautz1975'] = {'BBKL'},
['CITEREFFriedrich_Wilhelm_Bautz1990'] = {'BBKL'},
['CITEREFFry1964'] = {'RCTS-LocosLNER-7'},
['CITEREFFry1966'] = {'RCTS-LocosLNER-5'},
['CITEREFFrye1975'] = template_names['Cam_Hist_Iran'],
['CITEREFFrye1983'] = template_names['Cam_Hist_Iran'],
['CITEREFFrye2004'] = template_names['Iranica'],
['CITEREFFubini2012'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFFudenbergTirole1991'] = {'Cite Fudenberg Tirole 1991'},
['CITEREFFultonHarris1991'] = {'Fulton-Harris'},
----------< G >----------
['CITEREFGarakaniBrown2013'] = {'Encyclopaedia Islamica'},
['CITEREFGardner2005'] = {'MSW3 Microbiotheria'},
['CITEREFGardoni2015'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGareyJohnson1979'] = {'Garey-Johnson'},
['CITEREFGarsoian2000'] = template_names['Iranica'],
['CITEREFGarsoian2004'] = template_names['Iranica'],
['CITEREFGarsoian2005'] = template_names['Iranica'],
['CITEREFGarth2003'] = template_names['ME-ref'],
['CITEREFGazette34205'] = {'London Gazette'},
['CITEREFGazette34339'] = {'London Gazette'},
['CITEREFGazette34390'] = {'London Gazette'},
['CITEREFGazette34427'] = {'London Gazette'},
['CITEREFGazette34558'] = {'London Gazette'},
['CITEREFGazette34870'] = {'London Gazette'},
['CITEREFGazette34978'] = {'London Gazette'},
['CITEREFGazette34989'] = {'London Gazette'},
['CITEREFGazette35037'] = {'London Gazette'},
['CITEREFGazette35107'] = {'London Gazette'},
['CITEREFGazette35134'] = {'London Gazette'},
['CITEREFGazette35284'] = {'London Gazette'},
['CITEREFGazette37560'] = {'London Gazette'},
['CITEREFGazette37590'] = {'London Gazette'},
['CITEREFGazette37598'] = {'London Gazette'},
['CITEREFGazette37610'] = {'London Gazette'},
['CITEREFGazette38020'] = {'London Gazette'},
['CITEREFGazette38611'] = {'London Gazette'},
['CITEREFGeanakoplos1959'] = {'Emperor Michael Palaeologus and the West'},
['CITEREFGeorg_von_Dadelsen1953'] = template_names['NDB'],
['CITEREFGhanoonparvar1989'] = template_names['Iranica'],
['CITEREFGhereghlou2009'] = template_names['Iranica'],
['CITEREFGhereghlou2016'] = template_names['Iranica'],
['CITEREFGhulamiyan2015'] = template_names['Iranica'],
['CITEREFGhulamiyan2015'] = {'Encyclopaedia Islamica'},
['CITEREFGiannasi1975'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGibb1923'] = {'The Arab Conquests in Central Asia'},
['CITEREFGignoux1983'] = template_names['Iranica'],
['CITEREFGignoux1994'] = template_names['Iranica'],
['CITEREFGil1997'] = {'A History of Palestine, 634-1099', 'A History of Palestine, 634–1099'},
['CITEREFGillham2001'] = {'Gillham-Waterloo-City'},
['CITEREFGilliland1969'] = {'Gilliland'},
['CITEREFGilliland1994'] = {'Pop Chronicles 40s'},
['CITEREFGilliverMarshallWeiner2006'] = template_names['ME-ref'],
['CITEREFGilmanPeckColby1905'] = {'Cite NIE', 'New International Encyclopedia', 'NIE'},
['CITEREFGilmanPeckColby1916'] = {'New International Encyclopedia', 'NIE'},
['CITEREFGiunashvili2016'] = template_names['Iranica'],
['CITEREFGleaves1921'] = {'Gleaves'},
['CITEREFGlischinski1997'] = {'Glischinski-Santa Fe'},
['CITEREFGlöckner1983'] = {'Bach\'s compositions (sources)'},
['CITEREFGoldberg1981'] = {'Goldberg-Amtrak'},
['CITEREFGordon2001'] = {'Gordon-The Breaking of a Thousand Swords'},
['CITEREFGraham1974'] = {'Cite DCB'},
['CITEREFGrant1994'] = {'Grant-Death'},
['CITEREFGrant2010'] = {'Grant-Twilight'},
['CITEREFGrant2017'] = {'Grant-RailCo'},
['CITEREFGrassi2018'] = template_names['Iranica'],
['CITEREFGray1986'] = template_names['Cam_Hist_Iran'],
['CITEREFGreenlaw2007'] = {'Greenlaw-Via Rail'},
['CITEREFGregory1991'] = template_names['ODB'],
['CITEREFGregoryŠevčenko1991'] = template_names['ODB'],
['CITEREFGrete_Schemann1957'] = template_names['NDB'],
['CITEREFGrey2002'] = {'Australian Dictionary of Biography'},
['CITEREFGrierson1903'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1908'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1919'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1967'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGriffith1991'] = template_names['ODB'],
['CITEREFGriffithsSmith1999'] = {'Griffiths-Sheds1'},
['CITEREFGriffithsSmith2000'] = {'Griffiths-Sheds2'},
['CITEREFGrothendieck1955'] = {'Grothendieck Produits Tensoriels Topologiques et Espaces Nucléaires'},
['CITEREFGrothendieck1973'] = {'Grothendieck Topological Vector Spaces'},
['CITEREFGrothendieckDieudonné1960'] = {'EGA'},
['CITEREFGrothendieckDieudonné1961'] = {'EGA'},
['CITEREFGrothendieckDieudonné1963'] = {'EGA'},
['CITEREFGrothendieckDieudonné1964'] = {'EGA'},
['CITEREFGrothendieckDieudonné1965'] = {'EGA'},
['CITEREFGrothendieckDieudonné1966'] = {'EGA'},
['CITEREFGrothendieckDieudonné1967'] = {'EGA'},
['CITEREFGrothendieckDieudonné1971'] = {'EGA'},
['CITEREFGroves2005'] = {'MSW3 Primates', 'MSW3 Groves'},
['CITEREFGrubb2005'] = {'MSW3 Artiodactyla'},
['CITEREFGuilland1967'] = {'Recherches sur les institutions byzantines'},
['CITEREFGulino2005'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGunzburg1984'] = {'Gunzburg-History WAGR Steam'},
['CITEREFGurneyNabavi1993'] = template_names['Iranica'],
['CITEREFGutas1987'] = template_names['Iranica'],
['CITEREFGvakharia2001'] = template_names['Iranica'],
['CITEREFGüner1997'] = {'TDV Encyclopedia of Islam'},
----------< H >----------
['CITEREFHaarer2018'] = template_names['ODLA'],
['CITEREFHabibi2021'] = template_names['Iranica'],
['CITEREFHadidi2000'] = template_names['Iranica'],
['CITEREFHaji2008'] = template_names['Iranica'],
['CITEREFHaldon1999'] = {'Warfare, State and Society in the Byzantine World, 565–1204'},
['CITEREFHalliday1985'] = {'Halliday-AustWineCompend'},
['CITEREFHalliday2008'] = {'Halliday-JHWAtlasAust2008'},
['CITEREFHalliday2009'] = {'Halliday-AustWineEncyc'},
['CITEREFHalm1998'] = template_names['Iranica'],
['CITEREFHalpenny1990'] = {'Canadabio'},
['CITEREFHambly1990'] = template_names['Cam_Hist_Iran'],
['CITEREFHambly1991'] = template_names['Cam_Hist_Iran'],
['CITEREFHammondAnderson1993'] = template_names['ME-ref'],
['CITEREFHammondScull1995'] = template_names['ME-ref'],
['CITEREFHammondScull2005'] = template_names['ME-ref'],
['CITEREFHammondScull2006a'] = template_names['ME-ref'],
['CITEREFHammondScull2006b'] = template_names['ME-ref'],
['CITEREFHanaway1988'] = template_names['Iranica'],
['CITEREFHanaway1989'] = template_names['Iranica'],
['CITEREFHanawayLewisohn2004'] = template_names['Iranica'],
['CITEREFHans_Heinrich_Borcherdt1955'] = template_names['NDB'],
['CITEREFHans_Knudsen1972'] = template_names['NDB'],
['CITEREFHansen1988'] = {'Book-Hansen-US Nuclear Weapons'},
['CITEREFHansman1991'] = template_names['Iranica'],
['CITEREFHartshorne1977'] = {'Hartshorne AG'},
['CITEREFHassanpour1989'] = template_names['Iranica'],
['CITEREFHassanpour1995'] = template_names['Iranica'],
['CITEREFHasumi2003'] = {'Hasumi-shiguehiko-ozu-2003'},
['CITEREFHaswell-Smith2004'] = {'Haswell-Smith'},
['CITEREFHaugic1908'] = {'Schaff-Herzog'},
['CITEREFHawting1987'] = {'The First Dynasty of Islam'},
['CITEREFHawting2000'] = {'The First Dynasty of Islam'},
['CITEREFHaynes2011'] = {'RubberBible92nd'},
['CITEREFHeinichen1728'] = {'Bach\'s compositions (sources)'},
['CITEREFHeinrich_Welti1890'] = {'Cite ADB'},
['CITEREFHelgen2005'] = {'MSW3 Scandentia'},
['CITEREFHellmann1965'] = {'Bach\'s compositions (sources)'},
['CITEREFHenrici1725'] = {'Bach\'s compositions (sources)'},
['CITEREFHenryOrsmond1928'] = {'Raiatea family tree'},
['CITEREFHermann_Palm1876'] = {'Cite ADB'},
['CITEREFHerr2000'] = {'Herr-LN'},
['CITEREFHeschel2007'] = {'Encyclopaedia Judaica', 'Cite EJ', 'Cite Encyclopaedia Judaica'},
['CITEREFHewsen1988'] = template_names['Iranica'],
['CITEREFHidyHidyScottHofsummer2004'] = {'Hidy-Great Northern'},
['CITEREFHildHellenkemper1990'] = {'Tabula Imperii Byzantini'},
['CITEREFHildHellenkemper1994'] = {'Tabula Imperii Byzantini'},
['CITEREFHildRestle1981'] = {'Tabula Imperii Byzantini'},
['CITEREFHillenbrand1986'] = template_names['Iranica'],
['CITEREFHills,_Power_from_Steam'] = {'Book-Hills-Power from Steam'},
['CITEREFHills1989'] = {'Book-Hills-Power from Steam'},
['CITEREFHilmarJestremski2004'] = {'Schubert\'s compositions (references)'},
['CITEREFHilton1980'] = {'Hilton-Amtrak'},
['CITEREFHilton1990'] = {'Hilton Narrow Gauge'},
['CITEREFHiltonDue1960'] = {'Hilton-Interurban'},
['CITEREFHinton1986'] = {'HistoryofParliament'},
['CITEREFHirsch1906'] = {'Cite JE1906'},
['CITEREFHistoric_Environment_Scotland'] = {'Canmore'},
['CITEREFHistoric_Environment_Scotland1972'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland1976'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland2020'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland:_Rusco_Tower2020'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_ScotlandLB33744'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_ScotlandLB50114'] = {'Historic Environment Scotland'},
['CITEREFHob.'] = {'Schubert\'s compositions (references)'},
['CITEREFHoffmanSmith2005'] = {'MSW3 Lagomorpha'},
['CITEREFHoffmann1738'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1983'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1987'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1999'] = {'Bach\'s compositions (sources)'},
['CITEREFHolland1972'] = {'Holland-Vol 2'},
['CITEREFHolland1988'] = {'Cite DCB'},
['CITEREFHolland2001'] = {'Holland-Classic'},
['CITEREFHollingsworth1980'] = {'Hollingsworth-Atlas-Rigby'},
['CITEREFHollingsworth1991'] = template_names['ODB'],
['CITEREFHollingsworthCutler1991'] = template_names['ODB'],
['CITEREFHolmgren2003'] = {'EFloras'},
['CITEREFHoltBiddle1986'] = {'Holt-NorthWest'},
['CITEREFHolton1989'] = {'Holton-Reading-1'},
['CITEREFHonigmann1935'] = {'Byzance et les Arabes'},
['CITEREFHopley1983'] = {'Australian Dictionary of Biography'},
['CITEREFHort1911'] = {'DCBL'},
['CITEREFHorváth1966'] = {'Horváth Topological Vector Spaces and Distributions Volume 1 1966'},
['CITEREFHosseini2017'] = template_names['Iranica'],
['CITEREFHounshell1984'] = {'Hounshell1984'},
['CITEREFHudson1997'] = {'Country study'},
['CITEREFHughes1990'] = {'Hughes-IndianLocos1'},
['CITEREFHughes1992'] = {'Hughes-IndianLocos2'},
['CITEREFHughes1994'] = {'Hughes-IndianLocos3'},
['CITEREFHughes1996'] = {'Hughes-IndianLocos4'},
['CITEREFHummel1943'] = {'Cite ECCP'},
['CITEREFHumphreys2018'] = template_names['ODLA'],
['CITEREFHunter-Crawley2018'] = template_names['ODLA'],
['CITEREFHunter2008'] = {'Country study'},
['CITEREFHutter2009'] = template_names['Iranica'],
['CITEREFHutterer2005'] = {'MSW3 Soricomorpha'},
['CITEREFHütter2012'] = {'Hütter-50bis53'},
['CITEREFHütter2015'] = {'Hütter-54bis59'},
['CITEREFHütter2021'] = {'Hütter-60bis91'},
----------< I >----------
['CITEREFIbn_Khallikan1843'] = {'Ibn Khallikan\'s Biographical Dictionary'},
['CITEREFImber2002'] = {'Imber-The Ottoman Empire, 1300–1650'},
['CITEREFInalcik1989'] = {'Setton-A History of the Crusades'},
['CITEREFIranica:_Bahrām'] = template_names['Iranica'],
['CITEREFIrvine2006'] = template_names['Iranica'],
['CITEREFIshino1998'] = {'Teishajo'},
['CITEREFIshkevariNejad2008'] = {'Encyclopaedia Islamica'},
['CITEREFIvey1919'] = {'Ivey-Marquette'},
----------< J >----------
['CITEREFJackson1908'] = {'Schaff-Herzog'},
['CITEREFJackson1988'] = template_names['Iranica'],
['CITEREFJackson1989'] = template_names['Iranica'],
['CITEREFJackson1995'] = {'Cite enc-nyc'},
['CITEREFJackson2010'] = {'Cite enc-nyc2'},
['CITEREFJacksonMelville2001'] = template_names['Iranica'],
['CITEREFJacobs1904'] = {'Cite Jewish Encyclopedia'},
['CITEREFJarchow1981'] = {'Jarchow Locally Convex Spaces'},
['CITEREFJavadiBurrill1988'] = template_names['Iranica'],
['CITEREFJohn_O'Donovan1856'] = {'Cite AFM'},
['CITEREFJohnstonWelshSchafer2001'] = {'Johnston-Streamliner'},
['CITEREFJones2011'] = {'Cite EPD'},
['CITEREFJordan2002'] = {'Jordan-WineWABest'},
['CITEREFJoshi1983'] = {'Joshi Introduction to General Topology'},
['CITEREFJoslen2003'] = {'Joslen-OOB'},
['CITEREFJowett1867'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFJowett1989'] = {'Jowett-Atlas', 'Carnarvonshire Railway'},
['CITEREFJowett2000'] = {'Jowett-Nationalised'},
['CITEREFJullien2018'] = template_names['ODLA'],
['CITEREFJupp1986'] = {'HistoryofParliament'},
----------< K >----------
['CITEREFK.'] = {'Schubert\'s compositions (references)'},
['CITEREFKadinsky2016'] = {'Cite Hidden Waters NYC'},
['CITEREFKaegi1991'] = template_names['ODB'],
['CITEREFKamaly2006'] = template_names['Iranica'],
['CITEREFKamp1981'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFKang2008'] = {'Country study'},
['CITEREFKaramatiMelvin-Koushki2021'] = template_names['Iranica'],
['CITEREFKaramatiMelvin-Koushki2021'] = {'Encyclopaedia Islamica'},
['CITEREFKarimi-Hakkak1997'] = template_names['Iranica'],
['CITEREFKarimiMaghsoodi2013'] = {'Encyclopaedia Islamica'},
['CITEREFKarl_Frohnmeyer1953'] = template_names['NDB'],
['CITEREFKarnow1989'] = {'Cite-Karnow'},
['CITEREFKasheff2001'] = template_names['Iranica'],
['CITEREFKayvaniGholami2008'] = {'Encyclopaedia Islamica'},
['CITEREFKazhdan1991'] = template_names['ODB'],
['CITEREFKazhdanCutler1991'] = template_names['ODB'],
['CITEREFKazhdanJeffreys1991'] = template_names['ODB'],
['CITEREFKazhdanŠevčenko1991'] = template_names['ODB'],
['CITEREFKeall1987'] = template_names['Iranica'],
['CITEREFKeefe2006'] = {'Schubert\'s compositions (references)'},
['CITEREFKeller1937'] = {'Bach\'s compositions (sources)'},
['CITEREFKelly1988'] = {'Cite GEIL'},
['CITEREFKellyBurrage1920'] = {'Cite AMB1920'},
['CITEREFKennedy1998'] = {'The Cambridge History of Egypt', 'Cite Kennedy 1998', 'Cambridge History of Egypt'},
['CITEREFKennedy2001'] = {'Kennedy-The Armies of the Caliphs'},
['CITEREFKennedy2004'] = {'The Prophet and the Age of the Caliphates'},
['CITEREFKennedy2007'] = {'Kennedy-The Great Arab Conquests'},
['CITEREFKennedy2016'] = {'The Prophet and the Age of the Caliphates'},
['CITEREFKenyon2011'] = {'Bach\'s compositions (sources)'},
['CITEREFKerrigan1995'] = {'Shakespeare sonnets bibliography'},
['CITEREFKettenhofen1995'] = template_names['Iranica'],
['CITEREFKettenhofen2001'] = template_names['Iranica'],
['CITEREFKettenhofenBournoutianHewsen1998'] = template_names['Iranica'],
['CITEREFKhaleelulla1982'] = {'Khaleelulla Counterexamples in Topological Vector Spaces'},
['CITEREFKhaleghi-Motlagh1999'] = template_names['Iranica'],
['CITEREFKhaleghi-Motlagh2001'] = template_names['Iranica'],
['CITEREFKhan2012'] = {'Cite Banglapedia'},
['CITEREFKhatibiNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFKim1994'] = {'Country study'},
['CITEREFKirnberger1774'] = {'Bach\'s compositions (sources)'},
['CITEREFKirnberger1780'] = {'Bach\'s compositions (sources)'},
['CITEREFKlein2006'] = {'Klein-UP-2'},
['CITEREFKlíma1988'] = template_names['Iranica'],
['CITEREFKobayashi1978'] = {'Bach\'s compositions (sources)'},
['CITEREFKoderHild1976'] = {'Tabula Imperii Byzantini'},
['CITEREFKoderSoustalKoder1998'] = {'Tabula Imperii Byzantini'},
['CITEREFKoeppel2015'] = {'Cite citygrid'},
['CITEREFKofos1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFKohler1902'] = {'Cite Jewish Encyclopedia'},
['CITEREFKolde1914'] = {'Schaff-Herzog'},
['CITEREFKoliopoulos1978'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFKolmogorovFomin1957'] = {'Kolmogorov Fomin Elements of the Theory of Functions and Functional Analysis'},
['CITEREFKonrad_Ameln1985'] = template_names['NDB'],
['CITEREFKoska2011'] = {'Bach\'s compositions (sources)'},
['CITEREFKratville1962'] = {'Kratville-SSL'},
['CITEREFKretzschmar1910'] = {'Bach\'s compositions (sources)'},
['CITEREFKube2009'] = {'Schubert\'s compositions (references)'},
['CITEREFKurz1983'] = template_names['Cam_Hist_Iran'],
['CITEREFKuznik2008'] = {'Bach\'s compositions (sources)'},
['CITEREFKöthe1969'] = {'Köthe Topological Vector Spaces I'},
['CITEREFKöthe1979'] = {'Köthe Topological Vector Spaces II'},
['CITEREFKöthe1983'] = {'Köthe Topological Vector Spaces I'},
['CITEREFKülzer2008'] = {'Tabula Imperii Byzantini'},
['CITEREFKüçükaşcı2001'] = {'TDV Encyclopedia of Islam'},
----------< L >----------
['CITEREFLa_Porta2018'] = template_names['ODLA'],
['CITEREFLacourcière1974'] = {'Cite DCB'},
['CITEREFLadefogedMaddieson1996'] = {'SOWL'},
['CITEREFLandau-Tasseron2010'] = {'New Cambridge History of Islam'},
['CITEREFLandauCondit1996'] = {'Cite nysky'},
['CITEREFLandmann1907'] = {'Bach\'s compositions (sources)'},
['CITEREFLang1983'] = template_names['Cam_Hist_Iran'],
['CITEREFLangaroodiCooper2008'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiCooper2015'] = template_names['Iranica'],
['CITEREFLangaroodiCooper2015'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiNegahban2015'] = template_names['Iranica'],
['CITEREFLangaroodiNegahban2015'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroudi2001'] = template_names['Iranica'],
['CITEREFLatham1982–2021'] = template_names['Iranica'],
['CITEREFLazard1975'] = template_names['Cam_Hist_Iran'],
['CITEREFLaërtius1925'] = {'Cite Lives of the Eminent Philosophers', 'Cite LotEP'},
['CITEREFLeCoq1986'] = template_names['Iranica'],
['CITEREFLe_Quien1740'] = {'Oriens Christianus'},
['CITEREFLe_Strange1900'] = {'Baghdad During the Abbasid Caliphate'},
['CITEREFLe_Strange1905'] = {'Lands of the Eastern Caliphate'},
['CITEREFLe_Strange1922'] = {'Baghdad During the Abbasid Caliphate'},
['CITEREFLeblanc1979'] = {'Cite DCB'},
['CITEREFLee1903'] = {'Cite DNBIE'},
['CITEREFLee2018'] = template_names['ODLA'],
['CITEREFLeisingerWollny1993'] = {'Bach\'s compositions (sources)'},
['CITEREFLerner1988'] = template_names['Iranica'],
['CITEREFLev1999'] = {'Saladin in Egypt'},
['CITEREFLevitan2001'] = {'Springer'},
['CITEREFLewin1925'] = {'Lewin-EarlyRail'},
['CITEREFLewis1969'] = {'Setton-A History of the Crusades'},
['CITEREFLewis1986'] = {'Lewis-Shortline-1986'},
['CITEREFLewis1991'] = {'Lewis-Shortline-1991'},
['CITEREFLewis1996'] = {'Lewis-Shortline-1996'},
['CITEREFLewis2001'] = template_names['Iranica'],
['CITEREFLiederNet_Archive'] = {'Schubert\'s compositions (references)'},
['CITEREFLieu1997'] = template_names['Iranica'],
['CITEREFLighthouses_of_Australia_Inc'] = {'Cite loa'},
['CITEREFLind1986'] = {'Lind-Limiteds'},
['CITEREFLittle1974'] = {'Cite DCB'},
['CITEREFLongnon1969'] = {'Setton-A History of the Crusades'},
['CITEREFLosensky2003'] = template_names['Iranica'],
['CITEREFLoverance2018'] = template_names['ODLA'],
['CITEREFLukonin1983'] = {'Cambridge History of Iran'},
['CITEREFLurje2010'] = template_names['Iranica'],
['CITEREFLuttrell1975'] = {'Setton-A History of the Crusades'},
['CITEREFLuttrell1987'] = {'DBI'},
['CITEREFLynch2004'] = {'Lynch-Penn Central'},
['CITEREFLynch2005'] = {'Lynch-New Haven passenger'},
['CITEREFLynch2018'] = template_names['ODLA'],
['CITEREFLéger1990'] = {'Cite DCB'},
['CITEREFle_Fleming1953'] = {'RCTS-LocosGWR-8'},
['CITEREFle_Fleming1960'] = {'RCTS-LocosGWR-8'},
----------< M >----------
['CITEREFMacDermot1927'] = {'Infobox GWR'},
['CITEREFMacDermot1931'] = {'Infobox GWR'},
['CITEREFMacEoin1988'] = template_names['Iranica'],
['CITEREFMacKenzie1992'] = template_names['Iranica'],
['CITEREFMadelung1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMadelung1978'] = {'EI2'},
['CITEREFMadelung1983'] = template_names['Iranica'],
['CITEREFMadelung1984'] = template_names['Iranica'],
['CITEREFMadelung1988'] = template_names['Iranica'],
['CITEREFMadelung1993'] = template_names['Iranica'],
['CITEREFMadelung2003'] = template_names['Iranica'],
['CITEREFMadelungFelix1995'] = template_names['Iranica'],
['CITEREFMaeda2009'] = template_names['Iranica'],
['CITEREFMagdalino2002'] = {'The Empire of Manuel I Komnenos'},
['CITEREFMaiken1989'] = {'Maiken-Night Trains'},
['CITEREFMailer2004'] = {'Mailer-Omaha Road'},
['CITEREFMajidiNegahban'] = {'Encyclopaedia Islamica'},
['CITEREFMalandra2009'] = template_names['Iranica'],
['CITEREFManfred_Knedlik2007'] = {'BBKL'},
['CITEREFMarshak1994'] = template_names['Iranica'],
['CITEREFMarshak2002'] = template_names['Iranica'],
['CITEREFMarshall1823'] = {'Cite RNB1823'},
['CITEREFMarshall1824'] = {'Cite RNB1823'},
['CITEREFMarshall1825'] = {'Cite RNB1823'},
['CITEREFMarshall1827'] = {'Cite RNB1823'},
['CITEREFMarshall1828'] = {'Cite RNB1823'},
['CITEREFMarshall1829'] = {'Cite RNB1823'},
['CITEREFMarshall1830'] = {'Cite RNB1823'},
['CITEREFMarshall1831'] = {'Cite RNB1823'},
['CITEREFMarshall1832'] = {'Cite RNB1823'},
['CITEREFMarshall1833'] = {'Cite RNB1823'},
['CITEREFMarshall1835'] = {'Cite RNB1823'},
['CITEREFMarshall1972'] = {'Lancashire & Yorkshire Railway 3'},
['CITEREFMarshall2001'] = {'Marshall-INGSR'},
['CITEREFMartin_Persch1992'] = {'BBKL'},
['CITEREFMartin_Persch1993'] = {'BBKL'},
['CITEREFMartin_Persch1996'] = {'BBKL'},
['CITEREFMartindale1980'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMartindale1992'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMartindaleJonesMorris1971'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMasoud_Jalali-Moqaddam2015'] = {'Encyclopaedia Islamica'},
['CITEREFMatini1987'] = template_names['Iranica'],
['CITEREFMatthee2008'] = template_names['Iranica'],
['CITEREFMatthee2015'] = template_names['Iranica'],
['CITEREFMaul2005'] = {'Bach\'s compositions (sources)'},
['CITEREFMayGray2006'] = {'MayGray-WAGRPassCar'},
['CITEREFMazzaoui2002'] = template_names['Iranica'],
['CITEREFMcArthurMcArthur2003'] = {'Cite ogn', 'Cite Oregon Geographic Names'},
['CITEREFMcCaffrey1990'] = template_names['Iranica'],
['CITEREFMcCorduck2004'] = {'McCorduck 2004'},
['CITEREFMcCurdyRogers1902'] = {'Cite Jewish Encyclopedia'},
['CITEREFMcDonnell2015'] = {'McDonnell-Locomotives-2nd'},
['CITEREFMcGhee2008'] = {'Cite McGhee 2008'},
['CITEREFMeiningen1704'] = {'Bach\'s compositions (sources)'},
['CITEREFMeints1992'] = {'Meints-Companies'},
['CITEREFMeints2005'] = {'Meints-Lines'},
['CITEREFMelamed1988'] = {'Bach\'s compositions (sources)'},
['CITEREFMelamed1995'] = {'Bach\'s compositions (sources)'},
['CITEREFMelville1997'] = template_names['Iranica'],
['CITEREFMelville2003'] = template_names['Iranica'],
['CITEREFMennell1892'] = {'Dictionary of Australasian Biography'},
['CITEREFMetcalfe2009'] = {'The Muslims of Medieval Italy'},
['CITEREFMiddleton1961'] = {'Middleton-Interurban'},
['CITEREFMiddleton2001'] = {'Middleton-Electrified-2nd'},
['CITEREFMiddleton2002'] = {'Middleton-PRR-Under-Wire'},
['CITEREFMiddletonSmerkDiehl2007'] = {'Encyclopedia of North American Railroads'},
['CITEREFMiles1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMillar2011'] = {'NZR Steam Locomotive'},
['CITEREFMiller'] = {'Encyclopaedia Islamica'},
['CITEREFMiller1908'] = {'The Latins in the Levant', 'Latins in the Levant'},
['CITEREFMiller1921'] = {'Essays on the Latin Orient'},
['CITEREFMinnich2008'] = {'Country study'},
['CITEREFMiramar_Ship_Index'] = {'Csr', 'Cite ship register'},
['CITEREFMitchell1965'] = {'Mitchell TOC'},
['CITEREFMittermeierKonstantHawkinsLouis2006'] = {'LoM2'},
['CITEREFMittermeierLouisRichardsonSchwitzer2010'] = {'LoM3'},
['CITEREFMittermeierTattersallKonstantMeyers1994'] = {'LoM1'},
['CITEREFMoore1875'] = {'Cite CEM'},
['CITEREFMorana1993'] = {'Bach\'s compositions (sources)'},
['CITEREFMorony2009'] = template_names['Iranica'],
['CITEREFMoschonas1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFMottahedeh1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMozartHaydnHaydn2008'] = {'Schubert\'s compositions (references)'},
['CITEREFMunkres1974'] = {'Munkres Topology'},
['CITEREFMunkres2000'] = {'Munkres Topology'},
['CITEREFMurray2006'] = {'Murray-Illinois Central'},
['CITEREFMusserCarleton2005'] = {'MSW3 Muroidea'},
['CITEREFMüller,_Hans-Christian1966'] = template_names['NDB'],
----------< N >----------
['CITEREFNSA_II,_15'] = {'Schubert\'s compositions (references)'},
['CITEREFNSA_scores'] = {'Schubert\'s compositions (references)'},
['CITEREFNSA_website'] = {'Schubert\'s compositions (references)'},
['CITEREFNagel1990'] = template_names['Iranica'],
['CITEREFNariciBeckenstein2011'] = {'Narici Beckenstein Topological Vector Spaces'},
['CITEREFNavāʾī1988'] = template_names['Iranica'],
['CITEREFNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFNersessian2018'] = template_names['ODLA'],
['CITEREFNetzer1998'] = template_names['Iranica'],
['CITEREFNetzer2007'] = template_names['Iranica'],
['CITEREFNeukirch1999'] = {'Neukirch ANT'},
['CITEREFNeukirchSchmidtWingberg2000'] = {'Neukirch et al. CNF'},
['CITEREFNew_York_City_Landmarks_Preservation_CommissionDolkartPostal2009'] = {'Cite nycland'},
['CITEREFNewbould1999'] = {'Schubert\'s compositions (references)'},
['CITEREFNewman1994'] = template_names['Iranica'],
['CITEREFNicholsonCanepaDaryaee2018'] = template_names['ODLA'],
['CITEREFNicol1988'] = {'Byzantium and Venice: A Study in Diplomatic and Cultural Relations'},
['CITEREFNicol1992'] = {'The Immortal Emperor: The Life and Legend of Constantine Palaiologos, Last Emperor of the Romans'},
['CITEREFNicol1993'] = {'The Last Centuries of Byzantium, 1261–1453', 'The Last Centuries of Byzantium'},
['CITEREFNock1974'] = {'Nock-EustonGlasgow'},
----------< O >----------
['CITEREFO'Byrne1849'] = {'Cite NBD1849'},
['CITEREFO'ConnorRobertson1996'] = {'MacTutor Biography', 'MacTutor'},
['CITEREFO'ConnorRobertson2000'] = {'MacTutor Biography', 'MacTutor'},
['CITEREFO'Donoghue1897'] = {'Cite DNB'},
['CITEREFODB'] = template_names['ODB'],
['CITEREFODLA'] = template_names['ODLA'],
['CITEREFOberling1984'] = template_names['Iranica'],
['CITEREFOberling2008'] = template_names['Iranica'],
['CITEREFOberling2010'] = template_names['Iranica'],
['CITEREFOdisheli2018'] = template_names['ODLA'],
['CITEREFOfficial_Guide_of_the_Railways1950'] = {'Official Guide of the Railways'},
['CITEREFOgorek2012'] = {'Ogorek-South Shore'},
['CITEREFOikonomides1991'] = template_names['ODB'],
['CITEREFOikonomou1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFOlbrycht2021'] = template_names['Iranica'],
----------< P >----------
['CITEREFPLP'] = {'Prosopographisches Lexikon der Palaiologenzeit', 'PLP'},
['CITEREFPalmer1875'] = {'Cite ADB'},
['CITEREFPalmerStewart1965'] = {'Palmer & Stewart'},
['CITEREFPanainoAbdollahyBalland1990'] = template_names['Iranica'],
['CITEREFPandariHirtensteinNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFParvin2003'] = template_names['Iranica'],
['CITEREFParvin2009'] = template_names['Iranica'],
['CITEREFPatience1996'] = {'Patience-SteamTwilight'},
['CITEREFPatton2005'] = {'MSW3 Geomyidae'},
['CITEREFPaul2000'] = template_names['Iranica'],
['CITEREFPaxtonBourne1985'] = {'Paxton-Bourne'},
['CITEREFPeacock2011'] = template_names['Iranica'],
['CITEREFPeck1898'] = {'HDCA'},
['CITEREFPerlis2001'] = {'Springer'},
['CITEREFPerreault2004'] = {'Bach\'s compositions (sources)'},
['CITEREFPerry1983'] = template_names['Cam_Hist_Iran'],
['CITEREFPerry1990'] = template_names['Cam_Hist_Iran'],
['CITEREFPerry1991'] = template_names['Cam_Hist_Iran'],
['CITEREFPetropoulosKoumarianou1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFPetrucci1982'] = {'DBI'},
['CITEREFPezeshk2017'] = {'Encyclopaedia Islamica'},
['CITEREFPezeshkKhaleeli2017'] = template_names['Iranica'],
['CITEREFPezeshkKhaleeli2017'] = {'Encyclopaedia Islamica'},
['CITEREFPfau2008'] = {'Bach\'s compositions (sources)'},
['CITEREFPinkepank1973'] = {'Pinkepank diesel spotters guide 2'},
['CITEREFPlantlist2016'] = {'Plantlist'},
['CITEREFPlaten1976'] = {'Bach\'s compositions (sources)'},
['CITEREFPloumidisAlexiou1974'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFPmbZ'] = {'Prosopographie der mittelbyzantinischen Zeit', 'PMBZ'},
['CITEREFPolemis1968'] = {'Polemis-The Doukai'},
['CITEREFPope2007'] = {'Encyclopaedia Judaica', 'Cite EJ', 'Cite Encyclopaedia Judaica'},
['CITEREFPopplewell'] = {'Popplewell-Gazetteer'},
['CITEREFPotts2018'] = template_names['ODLA'],
['CITEREFPottsCanepa2018'] = template_names['ODLA'],
['CITEREFPourshariati2017'] = {'Encyclopædia Iranica Online'},
['CITEREFPozza1992'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFPrawer1985'] = {'Setton-A History of the Crusades'},
['CITEREFPritsak1991'] = template_names['ODB'],
['CITEREFProsopographie_der_mittelbyz._Zeit'] = {'Prosopographie der mittelbyzantinischen Zeit'},
----------< Q >----------
['CITEREFQuick2009'] = {'Quick-Stations'},
['CITEREFQuick2019'] = {'Quick-stations-5'},
['CITEREFQuinn2003'] = template_names['Iranica'],
----------< R >----------
['CITEREFRaditsa1983'] = template_names['Cam_Hist_Iran'],
['CITEREFRahman1983'] = template_names['Iranica'],
['CITEREFRaja'i1987'] = template_names['Iranica'],
['CITEREFRamaer1974'] = {'Ramaer-SteamLocosEAR'},
['CITEREFRansome-Wallis1971'] = {'Ransome-Wallis 1'},
['CITEREFRateliff2007'] = template_names['ME-ref'],
['CITEREFRavegnano2000'] = {'DBI'},
['CITEREFReed1953'] = {'RCTS-LocosGWR-2'},
['CITEREFReed1975'] = {'Reed-Streamline era'},
['CITEREFReed1997'] = {'Schubert\'s compositions (references)'},
['CITEREFReinhard_Tenberg1990'] = {'BBKL'},
['CITEREFRettinghaus2020'] = {'BDh'},
['CITEREFReynolds1921'] = {'Cite Collier\'s', 'Collier\'s'},
['CITEREFReynoldsOroszi2000'] = {'Reynolds-BO'},
['CITEREFRezaHirtensteinGholami2021'] = {'Encyclopaedia Islamica'},
['CITEREFRezakhani2018'] = template_names['ODLA'],
['CITEREFRezvani2014'] = template_names['Iranica'],
['CITEREFRichter-Bernburg2003'] = template_names['Iranica'],
['CITEREFRichter2018'] = {'BDh'},
['CITEREFRigo2005'] = template_names['ODB'],
['CITEREFRipleyDana1863'] = {'New American Cyclopedia'},
['CITEREFRipleyDana1864'] = {'New American Cyclopedia'},
['CITEREFRipleyDana1879'] = {'Cite AmCyc'},
['CITEREFRistaino1988'] = {'Country study'},
['CITEREFRobert_Eitner1891'] = {'Cite ADB'},
['CITEREFRobertson1983'] = {'Robertson-OriginScot'},
['CITEREFRoe1916'] = {'Roe1916'},
['CITEREFRoe1937'] = {'Roe1937'},
['CITEREFRoemer1986'] = template_names['Cam_Hist_Iran'],
['CITEREFRoemer1989'] = template_names['Iranica'],
['CITEREFRoemer2004'] = template_names['Iranica'],
['CITEREFRolt1965'] = {'Rolt1965'},
['CITEREFRoltKichenside1982'] = {'Rolt-Red'},
['CITEREFRose1857'] = {'Cite Newgenbio'},
['CITEREFRosenfeld1974'] = template_names['NDB'],
['CITEREFRosenzweigBlackmar1992'] = {'Cite Central Park History', 'Cite Central Park history'},
['CITEREFRowledge1975'] = {'Rowledge-Engines of the LMS'},
['CITEREFRowledge1993'] = {'Rowledge-Irish Steam Register'},
['CITEREFRowlett'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2007'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2012'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2013'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2016'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2017'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowson1998'] = template_names['Iranica'],
['CITEREFRudin1973'] = {'Rudin Walter Functional Analysis'},
['CITEREFRudin1991'] = {'Rudin Walter Functional Analysis'},
['CITEREFRunciman1951'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1951–1954'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1952'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1954'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1989'] = {'Runciman-A History of the Crusades'},
['CITEREFRussell1985'] = {'Setton-A History of the Crusades', 'Encyclopædia Iranica Online', 'Encyclopædia Iranica', 'Encyclopaedia Iranica', 'Cite Encyclopædia Iranica Online'},
['CITEREFRussell1986'] = template_names['Iranica'],
['CITEREFRussell1987'] = template_names['Iranica'],
['CITEREFRussellNorvig2003'] = {'Russell Norvig 2003'},
['CITEREFRybczynski2000'] = {'Rybczynski2000'},
['CITEREFRypka1968'] = template_names['Cam_Hist_Iran'],
----------< S >----------
['CITEREFSR_staff2013'] = {'Houston family tree'},
['CITEREFSadeghiTehrani2008'] = {'Encyclopaedia Islamica'},
['CITEREFSadıkoğlu1996'] = {'TDV Encyclopedia of Islam'},
['CITEREFSafa1987'] = template_names['Iranica'],
['CITEREFSafa1988'] = template_names['Iranica'],
['CITEREFSafa1989'] = template_names['Iranica'],
['CITEREFSafa1994'] = template_names['Iranica'],
['CITEREFSafa2003'] = template_names['Iranica'],
['CITEREFSajjadiAsatryanMelvin-Koushki'] = {'Encyclopaedia Islamica Online'},
['CITEREFSajjadiAsatryanMelvin-Koushki'] = {'Encyclopaedia Islamica'},
['CITEREFSajjadiAsatryanMelvin-Koushki2021'] = template_names['Iranica'],
['CITEREFSalbiev2021'] = template_names['Iranica'],
['CITEREFSalo2004'] = template_names['ME-ref'],
['CITEREFSamiʿiMelvin-Koushki2013'] = {'Encyclopaedia Islamica'},
['CITEREFSanders1998'] = {'The Cambridge History of Egypt', 'Cambridge History of Egypt'},
['CITEREFSanders2003'] = {'Sanders-Indiana'},
['CITEREFSanders2006'] = {'Sanders-Heartland'},
['CITEREFSanders2007'] = {'Sanders-Akron'},
['CITEREFSarikakis1974'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSaunders2001'] = {'Saunders-Merging Lines'},
['CITEREFSaunders2013'] = {'Saunders-Giants of the Seas'},
['CITEREFSavadaShaw1992'] = {'Country study'},
['CITEREFSavoryKaramustafa1998'] = template_names['Iranica'],
['CITEREFScarce1986'] = template_names['Iranica'],
['CITEREFSchaeferWolff1999'] = {'Schaefer Wolff Topological Vector Spaces'},
['CITEREFSchafer1996'] = {'Schafer-Classic-Railroads-1'},
['CITEREFSchafer1998'] = {'Schafer-Vintage Diesel'},
['CITEREFSchafer2000'] = {'Schafer-More-Classic'},
['CITEREFSchafer2003'] = {'Schafer-Classic-Railroads-3'},
['CITEREFSchaferSolomon1997'] = {'Schafer-Pennsylvania'},
['CITEREFSchaferWelsh1997'] = {'Schafer-Classic'},
['CITEREFSchaferWelsh2002'] = {'Schafer-Streamliners'},
['CITEREFSchaferWelshHolland2001'] = {'Schafer-American passenger train'},
['CITEREFSchaff-Herzog'] = {'Schaff-Herzog'},
['CITEREFSchechter1996'] = {'Schechter Handbook of Analysis and Its Foundations'},
['CITEREFScheide1960'] = {'Bach\'s compositions (sources)'},
['CITEREFSchicht1805'] = {'Bach\'s compositions (sources)'},
['CITEREFSchilling1997'] = {'Schilling-pop-culture'},
['CITEREFSchindel2013'] = template_names['Iranica'],
['CITEREFSchippmann1986'] = template_names['Iranica'],
['CITEREFSchippmann1987'] = template_names['Iranica'],
['CITEREFSchlitter2005'] = {'MSW3 Tubulidentata'},
['CITEREFSchlumberger1983'] = template_names['Cam_Hist_Iran'],
['CITEREFSchmieder1950'] = {'Bach\'s compositions (sources)'},
['CITEREFSchmieder1990'] = {'Bach\'s compositions (sources)'},
['CITEREFSchmitt1986'] = template_names['Iranica'],
['CITEREFSchmitt1989'] = template_names['Iranica'],
['CITEREFSchmitt1993'] = template_names['Iranica'],
['CITEREFSchmitt1994'] = template_names['Iranica'],
['CITEREFSchmitt1995'] = template_names['Iranica'],
['CITEREFSchmitt2002'] = template_names['Iranica'],
['CITEREFSchmitt2004'] = template_names['Iranica'],
['CITEREFSchmitt2005'] = template_names['Iranica'],
['CITEREFSchmitt2018'] = template_names['Iranica'],
['CITEREFSchmittBailey1986'] = template_names['Iranica'],
['CITEREFSchmitz1870'] = {'Cite DGRBM'},
['CITEREFSchneider1907'] = {'Bach\'s compositions (sources)'},
['CITEREFSchneider1912'] = {'Bach\'s compositions (sources)'},
['CITEREFScholze1736'] = {'Bach\'s compositions (sources)'},
['CITEREFSchroeter1961'] = {'Schroeter-Eisenbahnen'},
['CITEREFSchroeterRamaer1993'] = {'Schroeter-Ramaer-Eisenbahnen'},
['CITEREFSchubert-online'] = {'Schubert\'s compositions (references)'},
['CITEREFSchubert1968'] = {'Schubert Topology'},
['CITEREFSchulenberg2010'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulenberg2013'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1980'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1983'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1984'] = {'Bach\'s compositions (sources)'},
['CITEREFSchwieterman2001'] = {'Schwieterman-Leaves-Eastern'},
['CITEREFScottNegus2011'] = {'Scott-Negus-Cellar Door'},
['CITEREFScribbins1970'] = {'Scribbins-Hiawatha'},
['CITEREFScribbins2008'] = {'Scribbins-400-2008', 'Scribbins-Remembered'},
['CITEREFSearle'] = {'Cite sslidx'},
['CITEREFSegal1982'] = template_names['Iranica'],
['CITEREFSellwood1983'] = template_names['Cam_Hist_Iran'],
['CITEREFSemmensGoldfinch2000'] = {'Book-Semmens-Goldfinch-How Steam Locomotives Really Work'},
['CITEREFSemsarZand2008'] = {'Encyclopaedia Islamica'},
['CITEREFSetton1975'] = {'Setton-A History of the Crusades'},
['CITEREFSetton1976'] = {'The Papacy and the Levant'},
['CITEREFSetton1978'] = {'The Papacy and the Levant'},
['CITEREFSetton1984'] = {'The Papacy and the Levant'},
['CITEREFSettonHazard1975'] = {'Setton-A History of the Crusades'},
['CITEREFSfyroeras1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFShahbazi1986'] = template_names['Iranica'],
['CITEREFShahbazi1987'] = template_names['Iranica'],
['CITEREFShahbazi1988'] = template_names['Iranica'],
['CITEREFShahbazi1989'] = template_names['Iranica'],
['CITEREFShahbazi1991'] = template_names['Iranica'],
['CITEREFShahbazi1994'] = template_names['Iranica'],
['CITEREFShahbazi2002'] = template_names['Iranica'],
['CITEREFShahbazi2003'] = template_names['Iranica'],
['CITEREFShahbazi2004'] = template_names['Iranica'],
['CITEREFShahbazi2005'] = template_names['Iranica'],
['CITEREFShahbaziBosworth1990'] = template_names['Iranica'],
['CITEREFShahbaziRichter-Bernburg2002'] = template_names['Iranica'],
['CITEREFShaki1991'] = template_names['Iranica'],
['CITEREFShaughnessy1997'] = {'Shaughnessy-DH'},
['CITEREFShaw1978'] = {'Shaw-RailroadAccidents'},
['CITEREFShayegan2004'] = template_names['Iranica'],
['CITEREFShayesteh2013'] = template_names['Iranica'],
['CITEREFSheikhsofla2018'] = {'Encyclopaedia Islamica'},
['CITEREFShindo2004'] = {'Kaneto-shindo-shinario-jinsei'},
['CITEREFShoarian-SattariRezaeeNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFShoshani2005'] = {'MSW3 Shoshani'},
['CITEREFShtern2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSiegele1957'] = {'Bach\'s compositions (sources)'},
['CITEREFSilanos2014'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFSilke2006'] = {'O\'Donnell family tree'},
['CITEREFSimmons2005'] = {'MSW3 Chiroptera'},
['CITEREFSimon1966'] = {'Simon-Wines Australia'},
['CITEREFSimonWarner2011'] = {'Amtrak By the Numbers'},
['CITEREFSinclair1911'] = {'DCBL'},
['CITEREFSinger1905'] = {'Jewish Encyclopedia'},
['CITEREFSix1934'] = {'Cite Six', 'Cite six'},
['CITEREFSkjærvø2018'] = template_names['ODLA'],
['CITEREFSkoulatos1980'] = {'Les personnages byzantins de l\'Alexiade'},
['CITEREFSloan1964'] = {'Sloan1964'},
['CITEREFSmith1854'] = {'Cite DGRG', 'DGRG'},
['CITEREFSmith1870'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1873'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1876'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1880'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith2010'] = {'Smith-Cruise Ships-2010'},
['CITEREFSolomentsev2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSolomon2000'] = {'Solomon-American Diesel', 'Solomon-UP'},
['CITEREFSolomon2003'] = {'Solomon-Masterpieces'},
['CITEREFSolomon2004'] = {'Solomon-Amtrak'},
['CITEREFSolomon2005'] = {'Solomon-SP-Passenger'},
['CITEREFSolomon2006'] = {'Solomon-EMD Locomotives'},
['CITEREFSolomon2011'] = {'Solomon-Modern Diesel'},
['CITEREFSolomon2014'] = {'Solomon-GE and EMD'},
['CITEREFSolomonSchafer2007'] = {'Solomon-New York Central'},
['CITEREFSolopova2009'] = template_names['ME-ref'],
['CITEREFSoucek1982'] = template_names['Iranica'],
['CITEREFSoucek1983'] = template_names['Iranica'],
['CITEREFSoustal1991'] = {'Tabula Imperii Byzantini'},
['CITEREFSoustalKoder1981'] = {'Tabula Imperii Byzantini'},
['CITEREFSpielhoff1991'] = {'Spielhoff-EL'},
['CITEREFSpitta1894'] = {'Bach\'s compositions (sources)'},
['CITEREFSpitta1899'] = {'Bach\'s compositions (sources)'},
['CITEREFSpringirth2016'] = {'Springirth-Philadelphia'},
['CITEREFSpuhler1986'] = template_names['Cam_Hist_Iran'],
['CITEREFSpuler1983'] = template_names['Iranica'],
['CITEREFSpuler1987'] = template_names['Iranica'],
['CITEREFStagner1993'] = {'Stagner-Transition'},
['CITEREFStansfield1999'] = {'Stansfield-AyrRenfrew'},
['CITEREFStatistical_Yearbook_of_the_Republic_of_Croatia_2015'] = {'Croatia Yearbook 2015'},
['CITEREFStaufer1993'] = {'Staufer-Pennsy_III'},
['CITEREFStauferPennypacker1962'] = {'Staufer-Pennsy'},
['CITEREFStauferPennypacker1968'] = {'Staufer-Pennsy Power II'},
['CITEREFStaunton1988'] = {'Australian Dictionary of Biography'},
['CITEREFSternFishmanTilove2006'] = {'Cite New York 2000', 'Cite NY2000', 'Cite ny2000', 'Cite NY 2000', 'Cite ny 2000'},
['CITEREFSternGilmartinMassengale1983'] = {'Cite New York 1900', 'Cite NY1900'},
['CITEREFSternGilmartinMellins1987'] = {'Cite New York 1930', 'Cite NY 1930', 'Cite NY1930', 'Cite ny1930', 'Cite ny 1930'},
['CITEREFSternMellinsFishman1995'] = {'Cite New York 1960', 'Cite NY1960', 'Cite NY 1960', 'Cite ny1960', 'Cite ny 1960'},
['CITEREFSternMellinsFishman1999'] = {'Cite New York 1880', 'Cite NY1880', 'Cite NY 1880', 'Cite ny1880', 'Cite ny 1880'},
['CITEREFStewart1974'] = {'When Steam Was King'},
['CITEREFStrachey1981'] = template_names['ME-ref'],
['CITEREFStrickland1983'] = {'Strickland Locomotive Directory'},
['CITEREFStähelin1909'] = {'Schaff-Herzog'},
['CITEREFSuetin2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSundermann1988'] = template_names['Iranica'],
['CITEREFSusanne_Schurr1992'] = {'BBKL'},
['CITEREFSusanne_Siebert1992'] = {'BBKL'},
['CITEREFSvolopoulos1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSwartz1992'] = {'Swartz An Introduction to Functional Analysis'},
----------< T >----------
['CITEREFLondon_Gazette'] = {'London Gazette'},
['CITEREFTaber1977'] = {'Taber-DLW-19th'},
['CITEREFTaberTaber1980'] = {'Taber-DLW-20th-1'},
['CITEREFTaberTaber1981'] = {'Taber-DLW-20th-2'},
['CITEREFTafazzoli1999'] = template_names['Iranica'],
['CITEREFTafazzoli1999'] = {'Encyclopaedia Islamica'},
['CITEREFTafazzoli2000'] = template_names['Iranica'],
['CITEREFTalbot1991'] = template_names['ODB'],
['CITEREFTalbotKazhdan1991'] = template_names['ODB'],
['CITEREFTanındı2008'] = template_names['Iranica'],
['CITEREFTao2009'] = {'Cite Cambridge History of China'},
['CITEREFTer-Ghewondyan1976'] = {'The Arab Emirates in Bagratid Armenia'},
['CITEREFThe_London_Gazette1950'] = {'London Gazette'},
['CITEREFThe_London_Gazette_26_September_1919'] = {'London Gazette'},
['CITEREFThielemann2012'] = {'Bach\'s compositions (sources)'},
['CITEREFThomas1970'] = {'HistoryofParliament'},
['CITEREFThomas1971'] = {'Thomas-History-VI'},
['CITEREFThrush2010'] = {'HistoryofParliament'},
['CITEREFTikhomirov2001'] = {'Springer'},
['CITEREFTittel1966'] = {'Bach\'s compositions (sources)'},
['CITEREFTodt1996'] = {'BBKL'},
['CITEREFTodtVest2014'] = {'Tabula Imperii Byzantini'},
['CITEREFTolkien1937'] = template_names['ME-ref'],
['CITEREFTolkien1954'] = template_names['ME-ref'],
['CITEREFTolkien1955'] = template_names['ME-ref'],
['CITEREFTolkien1964'] = template_names['ME-ref'],
['CITEREFTolkien1966'] = template_names['ME-ref'],
['CITEREFTolkien1977'] = template_names['ME-ref'],
['CITEREFTolkien1980'] = template_names['ME-ref'],
['CITEREFTolkien1982'] = template_names['ME-ref'],
['CITEREFTolkien1983'] = template_names['ME-ref'],
['CITEREFTolkien1984'] = template_names['ME-ref'],
['CITEREFTolkien1985'] = template_names['ME-ref'],
['CITEREFTolkien1986'] = template_names['ME-ref'],
['CITEREFTolkien1987'] = template_names['ME-ref'],
['CITEREFTolkien1988'] = template_names['ME-ref'],
['CITEREFTolkien1989'] = template_names['ME-ref'],
['CITEREFTolkien1990'] = template_names['ME-ref'],
['CITEREFTolkien1992'] = template_names['ME-ref'],
['CITEREFTolkien1993'] = template_names['ME-ref'],
['CITEREFTolkien1994'] = template_names['ME-ref'],
['CITEREFTolkien1996'] = template_names['ME-ref'],
['CITEREFTolkien1998'] = template_names['ME-ref'],
['CITEREFTolkien1999'] = template_names['ME-ref'],
['CITEREFTolkien2007'] = template_names['ME-ref'],
['CITEREFTolkienSwan1978'] = template_names['ME-ref'],
['CITEREFTolkienTolkien1992'] = template_names['ME-ref'],
['CITEREFTonks1988'] = {'Tonks ironstone'},
['CITEREFTonks1989'] = {'Tonks ironstone'},
['CITEREFTonks1992'] = {'Tonks ironstone'},
['CITEREFTopping1975'] = {'Setton-A History of the Crusades'},
['CITEREFTorri2013'] = {'Bach\'s compositions (sources)'},
['CITEREFTougher2018'] = template_names['ODLA'],
['CITEREFToumanoff1986'] = template_names['Iranica'],
['CITEREFToumanoff2010'] = template_names['Iranica'],
['CITEREFToumanoffChaumont1987'] = template_names['Iranica'],
['CITEREFTourret1995'] = {'Tourret-Allied Military Locomotives'},
['CITEREFTrapp1991'] = template_names['ODB'],
['CITEREFTrappBeyerSturm-Schnabl1983'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTrappWaltherBeyer1976'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTrappWaltherBeyerSturm-Schnabl1978'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTreadgold1988'] = {'The Byzantine Revival, 780–842'},
['CITEREFTreadgold1997'] = {'A History of the Byzantine State and Society'},
['CITEREFTrèves2006'] = {'Trèves François Topological vector spaces, distributions and kernels'},
['CITEREFTucker2009'] = {'Encyclopaedia Islamica'},
['CITEREFTurim1998'] = {'Turim-oshima'},
['CITEREFTuring1950'] = {'Turing 1950'},
----------< U >----------
['CITEREFUS-NHub_Music_Deposit_31_(Klavierbüchlein_für_W._F._Bach)_at_Bach_Digital'] = {'Bach\'s compositions (sources)'},
['CITEREFUtas2002'] = template_names['Iranica'],
['CITEREFUwe_Eckardt2001'] = {'BBKL'},
['CITEREFunknown_author1881'] = {'Cite ADB'},
['CITEREFunknown_author1882'] = {'Cite ADB'},
----------< V >----------
['CITEREFVakalopoulos1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFVan_Cleve1969'] = {'Setton-A History of the Crusades'},
['CITEREFVan_Hoorickx1971'] = {'Schubert\'s compositions (references)'},
['CITEREFVan_Hoorickx_1974–1976'] = {'Schubert\'s compositions (references)'},
['CITEREFVan_Lint2018'] = template_names['ODLA'],
['CITEREFVan_Riemsdijk,_Compound_Locomotives'] = {'Book-Van Riemsdijk-Compound Locomotives'},
['CITEREFVan_Tricht2011'] = {'The Latin Renovatio of Byzantium'},
['CITEREFVandenberghen1989'] = {'Vandenberghen-SNCB12.2'},
['CITEREFVarzos1984'] = {'Η Γενεαλογία των Κομνηνών', 'Varzos-Genealogy of the Komnenoi'},
['CITEREFVasiliev1935'] = {'Byzance et les Arabes'},
['CITEREFVasiliev1968'] = {'Byzance et les Arabes'},
['CITEREFVendler1997'] = {'Shakespeare sonnets bibliography'},
['CITEREFVenetis2012'] = template_names['Iranica'],
['CITEREFVenn1954'] = {'VennAC'},
['CITEREFVesel1999'] = template_names['Iranica'],
['CITEREFVetter1713'] = {'Bach\'s compositions (sources)'},
['CITEREFVevainaCanepa2018'] = template_names['ODLA'],
['CITEREFVeysey1958'] = {'Veysey-PE-1958'},
['CITEREFVischer1912'] = {'Schaff-Herzog'},
['CITEREFVogelsang2003'] = template_names['Iranica'],
['CITEREFVolkmer1991'] = {'Volkmer-Pennsy-Electric'},
['CITEREFvan_Leyden1956'] = {'Bach\'s compositions (sources)'},
['CITEREFvan_Lint2018'] = template_names['ODLA'],
['CITEREFvon_Prantl1879'] = {'Cite ADB'},
----------< W >----------
['CITEREFWagnerBäzoldZschechLüderitz1990'] = {'Wagner-EFA2.3.2'},
['CITEREFWalter_Asmus1966'] = template_names['NDB'],
['CITEREFWayner1972'] = {'Wayner - Car names, numbers, consists'},
['CITEREFWayner1973'] = {'Wayner-Spotter-2nd'},
['CITEREFWebb2018'] = template_names['ODLA'],
['CITEREFWeber2016'] = template_names['Iranica'],
['CITEREFWechsler1979'] = {'Cite Cambridge History of China'},
['CITEREFWegman2008'] = {'Wegman-Illustrated'},
['CITEREFWeibel1994'] = {'Weibel IHA'},
['CITEREFWeinrebHibbertKeayKeay2008'] = {'London encyclopedia'},
['CITEREFWeisbrod1991'] = {'Weisbrod-EFA1.5'},
['CITEREFWeisbrodMüllerPetznik1978'] = {'Weisbrod-EFA1.2'},
['CITEREFWeiskopf1987'] = template_names['Iranica'],
['CITEREFWeiskopf1989'] = template_names['Iranica'],
['CITEREFWeiskopf1990'] = template_names['Iranica'],
['CITEREFWeiskopf1993'] = template_names['Iranica'],
['CITEREFWellhausen1927'] = {'The Arab Kingdom and its Fall'},
['CITEREFWells1982'] = {'Accents of English'},
['CITEREFWells2008'] = {'Cite LPD'},
['CITEREFWelsh2006'] = {'Welsh-Broadway'},
['CITEREFWelsh2008'] = {'Welsh-UP'},
['CITEREFWerner_Raupp2001'] = {'BBKL'},
['CITEREFWestcott1911'] = {'DCBL'},
['CITEREFWestermayer,_Georg1882'] = {'Cite ADB'},
['CITEREFWham1997'] = {'Wham-Ayrshire'},
['CITEREFWharton1991'] = template_names['ODB'],
['CITEREFWhishaw1842'] = {'Whishaw-RailofGB-2ndEd'},
['CITEREFWhishaw1969'] = {'Whishaw-RailofGB'},
['CITEREFWhite1985'] = {'White-Passenger-1985'},
['CITEREFWhite1993'] = {'White - American railroad freight car'},
['CITEREFWhiteWillenskyLeadon2010'] = {'Cite aia5'},
['CITEREFWhitehurst1973'] = {'Whitehurst GW Engines from 1940'},
['CITEREFWhittow1996'] = {'The Making of Byzantium, 600–1025'},
['CITEREFWickman1982'] = {'Country study'},
['CITEREFWiesehöfer1986'] = template_names['Iranica'],
['CITEREFWiesehöfer2018'] = template_names['ODLA'],
['CITEREFWilansky2013'] = {'Wilansky Modern Methods in Topological Vector Spaces'},
['CITEREFWillard2004'] = {'Willard General Topology'},
['CITEREFWilliams1998'] = {'Williams-Philadelphia'},
['CITEREFWilliams2003'] = {'Bach\'s compositions (sources)'},
['CITEREFWilliams2014'] = template_names['Iranica'],
['CITEREFWillis1750'] = {'Cite Notitia Parliamentaria'},
['CITEREFWilson2017'] = {'Wilson-Guide'},
['CITEREFWilsonFiske1891'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWilsonFiske1892'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWilsonFiske1900'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWiltshire2000'] = {'Lloyd-Margaret River'},
['CITEREFWinfieldLyon2004'] = {'Winfield'},
['CITEREFWinkler1883'] = template_names['ADB'],
['CITEREFWitakowski2018'] = template_names['ODLA'],
['CITEREFWolff1969'] = {'Setton-A History of the Crusades'},
['CITEREFWollny2015'] = {'Bach\'s compositions (sources)'},
['CITEREFWood1907'] = {'Cite Nuttall', 'Nuttall'},
['CITEREFWoodsKilpatrick2005'] = {'MSW3 Hystricognathi'},
['CITEREFWorden2008'] = {'Country study'},
['CITEREFWortley2010'] = {'John Skylitzes: A Synopsis of Byzantine History, 811–1057'},
['CITEREFWozencraft2005'] = {'MSW3 Carnivora'},
['CITEREFWright1979'] = {'Cite Cambridge History of China'},
['CITEREFWright2000'] = {'Bach\'s compositions (sources)'},
['CITEREFWägliJacobi2010'] = {'Schienennetz Schweiz'},
['CITEREFWürsch2013'] = template_names['Iranica'],
----------< X >----------
----------< Y >----------
['CITEREFYakubova2016'] = template_names['Iranica'],
['CITEREFYarshater1983'] = template_names['Iranica'],
['CITEREFYarshater1986'] = template_names['Cam_Hist_Iran'],
['CITEREFYarshater1988'] = template_names['Iranica'],
['CITEREFYarshater2018'] = template_names['Iranica'],
['CITEREFYarshater2021'] = template_names['Iranica'],
['CITEREFYazici2002'] = template_names['Iranica'],
['CITEREFYenne2005'] = {'Yenne-Chiefs'},
['CITEREFYildiz2004'] = template_names['Iranica'],
['CITEREFYonge1990'] = {'Quail-4'},
['CITEREFYonge1994'] = {'Quail-5'},
['CITEREFYonge2002'] = {'Quail-5'},
['CITEREFYonge2008'] = {'Quail-5'},
['CITEREFYonge2016'] = {'Quail-2-2016'},
['CITEREFYongePadgettSzwenk2013'] = {'Quail-4-Paper-3rdEd'},
['CITEREFYusofi1990'] = template_names['Iranica'],
----------< Z >----------
['CITEREFZahn1889–1893'] = {'Bach\'s compositions (sources)'},
['CITEREFZakeri2021'] = template_names['Iranica'],
['CITEREFZarrinkoubNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFZarrinkub1975'] = template_names['Cam_Hist_Iran'],
['CITEREFZeiniWiesehöfer2018'] = template_names['ODLA'],
['CITEREFZekulich2000'] = {'Zekulich-WineWA'},
['CITEREFZimmermann2004'] = {'Zimmermann-Burlington'},
['CITEREFZimmermann2007'] = {'Zimmermann-GrandLuxe'},
['CITEREFZuccaric._1747'] = {'Bach\'s compositions (sources)'},
----------< UNSORTED >----------
['CITEREFGazette27462'] = {'London Gazette'},
['CITEREFCawley2012'] = {'Medieval Lands by Charles Cawley'},
['CITEREFCrone2003'] = {'Slaves on Horses'},
['CITEREFΙστορία_του_Ελληνικού_Έθνους'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSpyropoulos1928'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFPikros1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFÖz1993'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzgüdenli2008'] = template_names['Iranica'],
['CITEREFÖzaydın2002'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzaydın2006'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzkuyumcu2006'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖztürk2013'] = {'TDV Encyclopedia of Islam'},
['CITEREFΜεγάλη_Στρατιωτικὴ_καὶ_Ναυτικὴ_Ἐγκυκλοπαιδεία'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFŞeşen1988'] = {'TDV Encyclopedia of Islam'},
['CITEREFFranke1994'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFTao2009'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFWechsler1979'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFWright1979'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFHistoric_England_Benty_Grange'] = {'NHLE'},
['CITEREFWalter1967'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFAliprantisBorder2006'] = {'Aliprantis Border Infinite Dimensional Analysis A Hitchhiker\'s Guide Third Edition'},
['CITEREFAmanat1985'] = template_names['Iranica'],
['CITEREFBaldwin1991'] = template_names['ODB'],
['CITEREFCallwell1999'] = {'Muni Chronology'},
['CITEREFHalmos1982'] = {'Halmos A Hilbert Space Problem Book 1982'},
['CITEREFHistoric_England'] = {'NHLE', 'National Heritage List for England'},
['CITEREFHitchins2001'] = template_names['Iranica'],
['CITEREFJohnson1906'] = {'BDA1906', 'Cite BDA1906'},
['CITEREFMachinery's_Handbook1996'] = {'MachinerysHandbook25e'},
['CITEREFMatthee2012'] = template_names['Iranica'],
['CITEREFNicholson2018'] = template_names['ODLA'],
['CITEREFNicol1968'] = {'The Byzantine Family of Kantakouzenos'},
['CITEREFWilsonFiske1889'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
}
--[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------
]]
return {
DNB_special_patterns = DNB_special_patterns,
DNB_template_names = template_names['DNB'],
special_patterns = special_patterns,
whitelist = whitelist,
wrapper_templates = wrapper_templates,
}
1aa09b54f21ebd45d55c0e11bec8783c21d7a4fa
Template:Link note
10
132
279
2022-08-23T14:39:36Z
Canopus >Jonesey95
0
Fix too small font per [[MOS:FONTSIZE]] when this template appears in reflists, e.g. at [[David Deutsch]]. Reflists are already at 90% of base font size.
wikitext
text/x-wiki
<span style="font-size:0.95em; font-size:95%; color:#555">({{{note|}}})</span><includeonly>{{#if:{{{cat|}}}|{{DMCA|{{{cat|}}}|from|{{{date|}}}}}}}</includeonly><noinclude>{{documentation}}</noinclude>
86089fa5a81775a10f0a53b58426a73b5c9a69ba
Template:Short description
10
65
145
2022-08-23T19:55:08Z
Canopus >Fayenatic london
0
Exclude category generation in user space, see [[Wikipedia:Categories_for_discussion/Log/2022_August_13#Category:User_pages_with_short_description]] – thanks to [[user:Vanisaac]] for sandboxing this
wikitext
text/x-wiki
{{#ifeq:{{lc:{{{1|}}}}}|none|<nowiki /><!--Prevents whitespace issues when used with adjacent newlines-->|<div class="shortdescription nomobile noexcerpt noprint searchaux" style="display:none">{{{1|}}}{{SHORTDESC:{{{1|}}}|{{{2|}}}}}</div>}}<includeonly>{{#ifeq:{{pagetype |defaultns = all |user=exclude}}|exclude||[[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with short description{{#ifeq:{{{pagetype}}}|Disambiguation pages|s}}]]}}</includeonly><!-- Start tracking
-->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using short description with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Short description]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | pagetype | bot |plural }}<!--
-->{{#ifexpr: {{#invoke:String|len|{{{1|}}}}}>100 | [[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with long short description]]}}<!--
-->{{Short description/lowercasecheck|{{{1|}}}}}<!--
-->{{Main other |{{SDcat |sd={{{1|}}} }} }}<noinclude>
{{Documentation}}
</noinclude>
a9562f8e6077b84b83132612ac9a5b37c58485b3
Category:Pages with ignored display titles
14
29
63
2022-08-27T14:24:00Z
SpaceMan
2
Created page with "Home page"
wikitext
text/x-wiki
Home page
9521dba25709a79ede4a34b50471419774c41099
Astronomy Database portal
0
30
64
2022-08-27T14:31:12Z
SpaceMan
2
Created page with "==Astronomy Database Portal== This is Astronomy Database Portal (ADP). Note: following content is taken from CDS ."
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from CDS .
d93cb94f20b5f7f0fce94caab73da93eda806d3a
65
64
2022-08-27T14:32:19Z
SpaceMan
2
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from [https://cds.u-strasbg.fr/ CDS] .
67b4aefc8fe0d54785a275aefa92aea5ebabf20b
71
65
2022-08-27T15:06:51Z
SpaceMan
2
/* Astronomy Database Portal */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from [https://cds.u-strasbg.fr/ CDS] .
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
431812e74fb6cade65be446d4cea72a4dd2aaf4d
VY Canis Major
0
31
67
2022-08-27T15:01:57Z
SpaceMan
2
VY Canis Major
wikitext
text/x-wiki
==Definition==
VY Canis Majoris or VY CMa is a red [[Hypergiant sta]]. It is located in the constellation [[Canis Major]]. It is one of the largest and brightest red hypergiants observed so far. It has a diameter of 1800 solar radii. This star emits energy very quickly and therefore, only exists for a few million years. It is estimated to be 4900 light years away from Earth. This star shows periodic light changes that last for approximately 2200 days.
==The crimson star==
The first known recorded observation of VY Canis Majoris is in the star catalogue of Jérôme Lalande, who recorded it on 7th March, 1801. Since 1847, VY CMa has been known to be a crimson star. Originally, University of Minnesota Professor Roberta M. Humphreys approximated that the radius of VY CMa is 1800-2100 times that of the Sun. This would make it the largest known star based on its radius.
==Surface==
This star also illustrates the conceptual problem of defining the "surface" of very large stars. This is very important for multiple reasons, including determining its radius and thus its size. It is a hundred thousand times less dense than the atmosphere of Earth (air) at sea level. Its average density is 0.000005 to 0.000010 kg per m³. Additionally, the star is constantly losing mass at an astounding rate. The boundary of such a star is usually defined by its "[[Rosseland Radius]]", which is based on its opaqueness to light.
48bb33dd2e981b39c6321e7f4feb688f22f249f5
69
67
2022-08-27T15:05:11Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
[[File:VY Canis Major.jpg|thumb|VY Canis Major]]
==Definition==
VY Canis Majoris or VY CMa is a red [[Hypergiant sta]]. It is located in the constellation [[Canis Major]]. It is one of the largest and brightest red hypergiants observed so far. It has a diameter of 1800 solar radii. This star emits energy very quickly and therefore, only exists for a few million years. It is estimated to be 4900 light years away from Earth. This star shows periodic light changes that last for approximately 2200 days.
==The crimson star==
The first known recorded observation of VY Canis Majoris is in the star catalogue of Jérôme Lalande, who recorded it on 7th March, 1801. Since 1847, VY CMa has been known to be a crimson star. Originally, University of Minnesota Professor Roberta M. Humphreys approximated that the radius of VY CMa is 1800-2100 times that of the Sun. This would make it the largest known star based on its radius.
==Surface==
This star also illustrates the conceptual problem of defining the "surface" of very large stars. This is very important for multiple reasons, including determining its radius and thus its size. It is a hundred thousand times less dense than the atmosphere of Earth (air) at sea level. Its average density is 0.000005 to 0.000010 kg per m³. Additionally, the star is constantly losing mass at an astounding rate. The boundary of such a star is usually defined by its "[[Rosseland Radius]]", which is based on its opaqueness to light.
03d971b276b3e76f93f238cce3d20f4813aacc8d
70
69
2022-08-27T15:05:41Z
SpaceMan
2
Protected "[[VY Canis Major]]" ([Edit=Allow only administrators] (indefinite))
wikitext
text/x-wiki
[[File:VY Canis Major.jpg|thumb|VY Canis Major]]
==Definition==
VY Canis Majoris or VY CMa is a red [[Hypergiant sta]]. It is located in the constellation [[Canis Major]]. It is one of the largest and brightest red hypergiants observed so far. It has a diameter of 1800 solar radii. This star emits energy very quickly and therefore, only exists for a few million years. It is estimated to be 4900 light years away from Earth. This star shows periodic light changes that last for approximately 2200 days.
==The crimson star==
The first known recorded observation of VY Canis Majoris is in the star catalogue of Jérôme Lalande, who recorded it on 7th March, 1801. Since 1847, VY CMa has been known to be a crimson star. Originally, University of Minnesota Professor Roberta M. Humphreys approximated that the radius of VY CMa is 1800-2100 times that of the Sun. This would make it the largest known star based on its radius.
==Surface==
This star also illustrates the conceptual problem of defining the "surface" of very large stars. This is very important for multiple reasons, including determining its radius and thus its size. It is a hundred thousand times less dense than the atmosphere of Earth (air) at sea level. Its average density is 0.000005 to 0.000010 kg per m³. Additionally, the star is constantly losing mass at an astounding rate. The boundary of such a star is usually defined by its "[[Rosseland Radius]]", which is based on its opaqueness to light.
03d971b276b3e76f93f238cce3d20f4813aacc8d
File:VY Canis Major.jpg
6
32
68
2022-08-27T15:04:07Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=VY Canis Major}}
|date=2022-08-27 20:32:42
|source={{own}}
|author=[[User:SpaceMan|SpaceMan]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
[[Category:Star]]
db6fb4412807d83d8706850354079c01c0da829e
Canopus
0
37
89
2022-09-01T02:49:57Z
Canopus >Prince Pugs
0
ahh I'm pretty stupid don't you think
wikitext
text/x-wiki
{{short description|Bright giant star in the constellation of Carina}}
{{Other uses}}
{{Starbox begin
| name=Canopus
}}
{{Starbox image
| image=[[File:Canopus.jpg|255px]]
| caption=An image of Canopus by [[Expedition 6]]
}}
{{Starbox observe
| epoch=J2000
| constell=[[Carina (constellation)|Carina]]
| pronounce={{IPAc-en|k|ə|ˈ|n|oʊ|p|ə|s}}<ref>{{OED|Canopus}}</ref>
| ra={{RA|06|23|57.10988}}<ref name="van Leeuwen2007">{{cite journal | title=Validation of the new Hipparcos reduction | last1=van Leeuwen | first1=F. | journal=Astronomy and Astrophysics | volume=474 | issue=2 | pages=653–664 | date=2007 | arxiv=0708.1752 | bibcode=2007A&A...474..653V | doi=10.1051/0004-6361:20078357 | s2cid=18759600 }} [http://webviz.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b48255b3&-out.add=.&-source=I/311/hip2&recno=30362 Vizier catalog entry ]</ref>
| dec={{DEC|-52|41|44.3810}}<ref name="van Leeuwen2007"/>
| appmag_v=−0.74<ref name="Ducati 2002">{{cite journal | title=Catalogue of Stellar Photometry in Johnson's 11-color system | last1=Ducati | first1=J. R. | journal=CDS/ADC Collection of Electronic Catalogues | volume=2237 | pages=0 | date=2002 | bibcode=2002yCat.2237....0D }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b360304a&-out.add=.&-source=II/237/colors&recno=1155 Vizier catalog entry ]</ref>
}}
{{Starbox character
| type=
| class=A9 II<ref name=perkins>{{cite journal|bibcode=1989ApJS...69..301G|title=The early F-type stars – Refined classification, confrontation with Stromgren photometry, and the effects of rotation|journal=Astrophysical Journal Supplement Series|volume=69|pages=301|last1=Gray|first1=R. O.|last2=Garrison|first2=R. F.|year=1989|doi=10.1086/191315}}</ref><ref>{{cite journal|bibcode=1993ASPC...45...59L|title=A Spectroscopic Study of High Galactic Latitude F Supergiant Stars|journal=Luminous High-Latitude Stars. The International Workshop on Luminous High-Latitude Stars|volume=45|pages=59|last1=Lopez-Cruz|first1=O.|last2=Garrison|first2=R. F.|year=1993}}</ref>
| b-v=+0.15<ref name="Ducati 2002"/>
| u-b=+0.10<ref name="Ducati 2002"/>
| variable=
}}
{{Starbox astrometry
| radial_v={{val|20.3|0.5}}<ref name="Gontcharov 2007">{{cite journal | title=Pullkovo Compilation of Radial Velocities for 39495 Hipparcos stars in a common system | last1=Gontcharov | first1=G. A. | journal=Astronomy Letters | volume=32 | issue=1 | pages=759–771 | date=2007 | bibcode=2006AstL...32..759G | doi=10.1134/S1063773706110065|arxiv = 1606.08053 | s2cid=119231169 }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b5f60fbd&-out.add=.&-source=III/252/table8&recno=9232 Vizier catalog entry ]</ref>
| prop_mo_ra=19.93<ref name="van Leeuwen2007"/>
| prop_mo_dec=23.24<ref name="van Leeuwen2007"/>
| parallax=10.55
| p_error=0.56
| parallax_footnote=<ref name="van Leeuwen2007"/>
| absmag_v=–5.71<ref name=smiljanic2006/>
|arxiv = 1606.08053 }}
{{Starbox detail
| metal_fe=–0.07<ref name=smiljanic2006/>
| mass={{Val|8.0|0.3}}<ref name=vlti>{{cite journal|bibcode=2013MNRAS.434..437C|arxiv=1306.3288|title=Fundamental parameters of 16 late-type stars derived from their angular diameter measured with VLTI/AMBER|journal=Monthly Notices of the Royal Astronomical Society|volume=434|issue=1|pages=437–450|last1=Cruzalèbes|first1=P.|last2=Jorissen|first2=A.|last3=Rabbia|first3=Y.|last4=Sacuto|first4=S.|last5=Chiavassa|first5=A.|last6=Pasquato|first6=E.|last7=Plez|first7=B.|last8=Eriksson|first8=K.|last9=Spang|first9=A.|last10=Chesneau|first10=O.|year=2013|doi=10.1093/mnras/stt1037|s2cid=49573767}}</ref> (2013)<br/>{{val|10.1|0.1}}<ref name=Tetzlaff2011/> (2011)
| radius={{Val|71|4}}<ref name=vlti/> (2013)<br>{{val|73.3|5.2}}<ref name=DomicianoDeSouza>{{cite journal|doi=10.1051/0004-6361/202140478|title=Refined fundamental parameters of Canopus from combined near-IR interferometry and spectral energy distribution|year=2021|last1=Domiciano De Souza|first1=A.|last2=Zorec|first2=J.|last3=Millour|first3=F.|last4=Le Bouquin|first4=J.-B.|last5=Spang|first5=A.|last6=Vakili|first6=F.|journal=Astronomy & Astrophysics|volume=654|pages=A19|arxiv=2109.07153|bibcode=2021A&A...654A..19D|s2cid=237513623}}</ref> (2021)
| gravity={{Val|1.70|0.05}}<ref name=DomicianoDeSouza/>
| rotational_velocity=9<ref name=ayres2018/>
| rotation={{val|298|u=days|p=≥}}<ref name=Testa2004/>
| luminosity=10,700<ref name=vlti/>
| temperature=7,400<ref name=ayres2018>{{cite journal |bibcode=2018ApJ...854...95A |title=Cracking the Conundrum of F-supergiant Coronae |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |year=2018 |volume=854 |issue=2 |page=95 |doi=10.3847/1538-4357/aaa6d7 |arxiv=1802.02552 |s2cid=119101035 }}</ref>
| age_myr = {{val|25.1|2.5}}<ref name=Tetzlaff2011>{{cite journal | title=A catalogue of young runaway Hipparcos stars within 3 kpc from the Sun | last1=Tetzlaff | first1=N. | last2=Neuhäuser | first2=R. | last3=Hohle | first3=M. M. | journal=Monthly Notices of the Royal Astronomical Society | volume=410 | issue=1 | pages=190–200 | date=January 2011 | doi=10.1111/j.1365-2966.2010.17434.x | arxiv=1007.4883 | bibcode=2011MNRAS.410..190T | s2cid=118629873 }}</ref>
}}
{{Starbox catalog
| names={{odlist | name=Suhayl | name2=Suhel | name3=Suhail | B=α Carinae | CPD=−52°1941 | FK5=245 | HD=45348 | HIP=30438 | HR=2326 | SAO=234480| GC=8302 }}<ref name=SIMBAD>{{cite simbad | title=alf Car | access-date=2019-03-09 }}</ref>
}}
{{Starbox reference
| Simbad=canopus
}}
{{Starbox end}}
'''Canopus''' is the brightest star in the southern [[constellation]] of [[Carina (constellation)|Carina]] and the [[list of brightest stars|second-brightest star]] in the [[night sky]]. It is also [[Bayer designation|designated]] '''α Carinae''', which is [[Latinisation of names|Latinised]] to '''Alpha Carinae'''. With a [[visual apparent magnitude]] of −0.74, it is outshone only by [[Sirius]]. Located around {{val|310|ul=light-years}} from the [[Sun]], Canopus is a [[bright giant]] of [[spectral type A9]], so it is essentially white when seen with the naked eye. It has a luminosity over 10,000 times the [[luminosity of the Sun]], is eight times as [[mass of the Sun|massive]], and has expanded to 71 times the [[Sun's radius]]. Its enlarged [[photosphere]] has an [[effective temperature]] of around {{val|7,400|fmt=commas|u=K}}. Canopus is undergoing [[stellar core|core]] [[helium fusion|helium burning]] and is currently in the so-called [[blue loop]] phase of its [[stellar evolution|evolution]], having already passed through the [[red-giant branch]] after exhausting the hydrogen in its core. Canopus is a [[X-ray astronomy|source of X-rays]], which are likely being emitted from its [[stellar corona|corona]].
The prominent appearance of Canopus means it has been the subject of mythological lore among many ancient peoples. Its proper name is generally considered to originate from the [[Greek mythology|mythological]] [[Canopus (mythology)|Canopus]], who was a navigator for [[Menelaus]], king of [[Sparta]]. The [[acronychal rising]] marked the date of the Ptolemaia festival in Egypt. In ancient India, it was named [[Agastya]] after the revered [[Vedas|Vedic]] sage. For Chinese astronomers, it was known as the [[Old Man of the South Pole]].
==Nomenclature==
The name ''Canopus'' is a Latinisation of the [[Ancient Greek]] name Κάνωβος/Kanôbos, recorded in Claudius Ptolemy's ''[[Almagest]]'' (c.150 AD). Eratosthenes used the same spelling.<ref name="ridpathCr"/> Hipparchos wrote it as Κάνωπος. [[John Flamsteed]] wrote Canobus,<ref>{{cite book|last=Flamsteed|first=John|title=Atlas coelestis|location=London, United Kingdom|date=1729|pages=Constellation Map of Southern Hemisphere|url=http://lhldigital.lindahall.org/u?/astro_atlas,1191}}</ref> as did [[Edmond Halley]] in his 1679 ''Catalogus Stellarum Australium''.<ref name="Halley 1679">{{cite book|last=Halley|first=Edmond|title=Catalogus stellarum australium; sive, Supplementum catalogi Tychenici, exhibens longitudines et latitudines stellarum fixarum, quae, prope polum Antarcticum sitae, in horizonte Uraniburgico Tychoni inconspicuae fuere, accurato calculo ex distantiis supputatas, & ad annum 1677 completum correctas...Accedit appendicula de rebus quibusdam astronomicis|publisher=T. James|location=London|date=1679|pages=30|url=http://babel.hathitrust.org/cgi/pt?id=mdp.39015007000170;view=1up;seq=41;size=150}}</ref> The name has two possible derivations, both listed in [[Richard Hinckley Allen]]'s seminal ''[[Star Names: Their Lore and Meaning]]''.
* [[Argo Navis]] was the ship used by [[Jason]] and the Argonauts in the legend of the [[Trojan War]]. The brightest star in the constellation was given the name of a ship's pilot from another Greek legend: [[Canopus (mythology)|Canopus]], pilot of [[Menelaus]]' ship on his quest to retrieve [[Helen of Troy]] after she was taken by [[Paris (mythology)|Paris]].<ref name="hinkley63">{{cite book|first=Richard Hinckley|last=Allen|author-link=Richard Hinckley Allen|date=1963|orig-year=1899|title=Star Names: Their Lore and Meaning|pages=[https://archive.org/details/starnamestheirlo00alle/page/67 67–72]|edition=Revised|publisher=Dover Publications|location=New York|isbn=0-486-21079-0|url-access=registration|url=https://archive.org/details/starnamestheirlo00alle/page/67}}</ref>
* A ruined ancient Egyptian port named [[Canopus, Egypt|Canopus]] lies near the mouth of the [[Nile]], site of the [[Battle of the Nile]]. It is speculated that its name is derived from the Egyptian [[Coptic language|Coptic]] ''Kahi Nub'' ("Golden Earth"), which refers to how Canopus would have appeared near the horizon in [[ancient Egypt]], reddened by atmospheric extinction from that position.<ref name="hinkley63"/><ref name=lynn1905>{{cite journal |bibcode=1905Obs....28..289L |title=The brightest fixed star and its name |last1=Lynn |first1=W. T. |journal=The Observatory |year=1905 |volume=28 |page=289 }}</ref>
In 2016, the [[International Astronomical Union]] organized a [[IAU Working Group on Star Names|Working Group on Star Names]] (WGSN) to catalog and standardize proper names for stars.<ref name="WGSN">{{cite web | url=https://www.iau.org/science/scientific_bodies/working_groups/280/ | title=IAU Working Group on Star Names (WGSN) | website=iau.org | publisher=[[International Astronomical Union]] | access-date=22 May 2016}}</ref> The WGSN's first bulletin of July 2016 included a table of the first two batches of names approved by the WGSN, which included ''Canopus'' for this star.<ref name="WGSN1">{{cite web | url=https://www.iau.org/static/science/scientific_bodies/working_groups/280/WGSN_bulletin1.pdf | title=Bulletin of the IAU Working Group on Star Names, No. 1 | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06 }}</ref> Canopus is now included in the ''IAU Catalog of Star Names''.<ref name="IAU-CSN">{{cite web | url=https://www.iau.org/public/themes/naming_stars/ | title=IAU Catalog of Star Names | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06}}</ref>
Canopus traditionally marked the rudder of the ship [[Argo Navis]].<ref>{{cite journal | title = On Frederick de Houtman's Catalogue of Southern Stars, and the Origin of the Southern Constellations | last1= Knobel|first1=E. B. |journal = [[Monthly Notices of the Royal Astronomical Society]] | volume= 77| issue= 5 | pages=414–432 [422] | bibcode = 1917MNRAS..77..414K |date=1917 | doi=10.1093/mnras/77.5.414| doi-access=free }}</ref> German celestial cartographer [[Johann Bayer]] gave it—as the brightest star in the constellation—the [[Bayer designation|designation]] of ''α Argus'' ([[Latinisation of names|Latinised]] to ''Alpha Argus'') in 1603. In 1763, French astronomer [[Nicolas Louis de Lacaille]] divided the huge constellation into three smaller ones,<ref name=Glass2012>{{cite book | title=Nicolas-Louis De La Caille, Astronomer and Geodesist | first=Ian Stewart | last=Glass | date=November 17, 2012 | page=73 | isbn=9780191649608 | publisher=OUP Oxford | url=https://www.google.com/books/edition/Nicolas_Louis_De_La_Caille_Astronomer_an/eZjlHAIBeRAC?hl=en&gbpv=1&pg=PT73 }}</ref> and hence Canopus became ''α Carinae'' ([[Latinisation of names|Latinised]] to ''Alpha Carinae''). It is listed in the [[Bright Star Catalogue]] as HR 2326, the [[Henry Draper Catalogue]] as HD 45348, and the [[Hipparcos catalogue]] as HIP 30438.<ref name=SIMBAD/> Flamsteed did not number this southern star, but [[Benjamin Apthorp Gould]] gave it the number 7 (7 G. Carinae) in his ''Uranometria Argentina''.<ref name=Gould1878>{{cite journal | title=Uranometria Argentina: Brightness and position of every fixed star, down to the seventh magnitude, within one hundred degrees of the South Pole; with atlas | last=Gould | first=Benjamin Apthorp | journal=Resultados del Observatorio Nacional Argentino | volume=1 | page=140 | date=1878 | bibcode=1879RNAO....1....1G }}</ref>
An occasional name seen in English is ''Soheil'', or the feminine Soheila; in Turkish is ''Süheyl'', or the feminine Süheyla, from the Arabic name for several bright stars, سهيل ''suhayl'',<ref name="hinkley63"/> and Canopus was known as Suhel {{IPAc-en|'|s|uː|h|E|l}} in medieval times.<ref name=kunitzsch/> Alternative spellings include Suhail, Souhail, Suhilon, Suheyl, Sohayl, Suhayil, Shoel, Sohil, Soheil, Sahil, Suhayeel, Sohayil, Sihel, and Sihil.<ref name="hinkley63"/> An alternative name was ''Wazn'' "weight" or ''Haḍar'' "ground", possibly related to its low position near the horizon.<ref name="hinkley63"/> Hence comes its name in the ''[[Alfonsine tables]]'', Suhel ponderosus, a Latinization of ''Al Suhayl al Wazn''.<ref name="hinkley63"/> Its Greek name was revived during the [[Renaissance]].<ref name=kunitzsch>{{cite book |last1=Kunitzsch|first1=Paul |last2=Smart|first2=Tim |date = 2006|title = A Dictionary of Modern star Names: A Short Guide to 254 Star Names and Their Derivations |edition = 2nd rev. |publisher = Sky Publishing Corporation |location = Cambridge, Massachusetts |isbn = 978-1-931559-44-7 |page = 23}}</ref>
==Observation==
[[File:Carina constellation map.svg|thumb|left|The constellation [[Carina (constellation)|Carina]] with Canopus towards the right (west)]]
The Spanish Muslim astronomer [[Ibn Rushd]] went to [[Marrakesh]] (in Morocco) to observe the star in 1153, as it was invisible in his native [[Córdoba, Spain|Córdoba]], [[Al-Andalus]]. He used the different visibility in different latitudes to argue that the [[Spherical Earth|earth is round]], following [[Spherical Earth#Aristotle|Aristotle's argument]] which held that such an observation was only possible if the earth was a relatively small sphere.<ref name=ibn_rushd>{{cite encyclopedia|first1=Juan|last1=Vernet|author-link1=Juan Vernet|first2=Julio|last2=Samsó|author-link2=Julio Samsó |title=The development of Arabic science in Andalusia |page=264|editor=[[Roshdi Rashed]]|encyclopedia=Encyclopedia of the History of Arabic Science | date=1996|publisher=Routledge|isbn=978-0-415-12410-2|oclc=912501823}}</ref>
English explorer [[Robert Hues]] brought Canopus to the attention of European observers in his 1592 work ''Tractatus de Globis'', along with [[Achernar]] and [[Alpha Centauri]], noting:<blockquote>"Now, therefore, there are but three [[First-magnitude star|Stars of the first magnitude]] that I could perceive in all those parts which are never seene here in England. The first of these is that bright Star in the sterne of [[Argo Navis|Argo]] which they call Canobus. The second is in the end of [[Eridanus (constellation)|Eridanus]]. The third is in the right foote of the [[Centaurus|Centaure]]."<ref>Knobel, p. 416.</ref></blockquote>
[[File:Vela and Surrounding Constellations (ground-based image).jpg|right|thumb|Wide angle view showing Canopus and other prominent stars with the Milky Way|alt=A field of stars against the Milky Way background with the prominent stars and constellations labelled]]
In the [[Southern Hemisphere]], Canopus and [[Sirius]] are both visible high in the sky simultaneously, and reach a [[meridian (astronomy)|meridian]] just {{val|21|u=minutes}} apart. Brighter than [[first-magnitude star|first magnitude]], Canopus can be seen by naked eye in the early twilight. Mostly visible in mid to late summer in the Southern Hemisphere, Canopus [[Culmination|culminates]] at midnight on December 27,<ref name="motz" /> and at 9 PM on February 11.<ref name="Schaaf257">Schaaf, p. 257.</ref>
When seen from latitudes south of {{DEC|37|18}} S, Canopus is a [[circumpolar star]]. Since Canopus is so far south in the sky, it never rises in mid- to far-northern latitudes; in theory the northern limit of visibility is latitude {{DEC|37|18}} north. This is just south of [[Athens]], [[Richmond, Virginia]] (USA), and [[San Francisco]], and very close to [[Seville]] and [[Agrigento]]. It is almost exactly the latitude of [[Lick Observatory]] on [[Mount Hamilton (California)|Mt. Hamilton, California]], from which it is readily visible because of the effects of elevation and [[atmospheric refraction]], which add another degree to its apparent altitude. Under ideal conditions, it can be spotted as far north as latitude {{DEC|37|31}} from the Pacific coast.<ref>D. Gieringer, "Exploring the Tropic of Canopus", ''Astronomy'', December 1985, p.24.</ref> Another northernmost record of visibility came from [[Mount Nemrut]] in Turkey, latitude {{DEC|37|59}}.<ref>{{cite web |last1=Tezel |first1=Tunç |author-link=Tunç Tezel |url=http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |title=Zodiacal Light and Nemrut Heritage |work=The World At Night (TWAN) |access-date=17 March 2014 |date=8 Oct 2013 |archive-url=https://web.archive.org/web/20140317134955/http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |archive-date=17 March 2014 |url-status=dead }}</ref> It is more easily visible in places such as the Gulf Coast and Florida, and the island of [[Crete]] (Greece) where the best season for viewing it around 9 p.m. is during late January and early February.<ref name="motz">{{cite book|last1=Motz|first1=Lloyd|last2=Nathanson|first2=Carol|title=The Constellations: An Enthusiast's Guide to the Night Sky|publisher=Aurum Press|location=London, United Kingdom|date=1991|pages=376–77|isbn=1-85410-088-2}}</ref>
Canopus has a B–V [[color index]] of +0.15—where 0 is a blue-white—indicating it is essentially white, although it has been described as yellow-white. Canopus' spectral type has been given as F0 and the incrementally warmer A9. It is less yellow than [[Altair]] or [[Procyon]], with indices measured as 0.22 and 0.42, respectively.<ref name=Hoffleit1991>{{cite book | title=Bright Star Catalogue | edition=5th Revised | last1=Hoffleit | first1=D. | last2=Warren Jr. | first2=W. H. | date=1991 | publisher=[[Centre de Données astronomiques de Strasbourg|CDS]] }}</ref> Some observers may have perceived Canopus as yellow-tinged because it is low in the sky and hence subject to atmospheric effects.<ref name="Schaaf112">Schaaf, pp. 112–13.</ref> [[Patrick Moore]] said that it never appeared anything but white to him.<ref name="moore2000">{{cite book | first1=Patrick | last1=Moore | title=Exploring the night sky with binoculars | edition=4th | publisher=Cambridge University Press | year=2000 | isbn=9780521793902 | page=[https://archive.org/details/exploringnightsk00moor/page/69 69] | url=https://archive.org/details/exploringnightsk00moor| url-access=registration }}</ref> The [[bolometric correction]] for Canopus is 0.00,<ref name=smiljanic2006/> indicating that the visual [[absolute magnitude]] and bolometric absolute magnitude are equal.
Canopus was previously proposed to be a member of the [[Scorpius–Centaurus association]], however it is not located near the subgroups of that association, and has not been included as a Sco-Cen member in kinematic studies that used [[Hipparcos]] astrometric data.<ref name="deZeeuw">{{cite journal|last1=de Zeeuw|first1=P.T. |last2=Hoogerwerf|first2=R. |last3=de Bruijne|first3=J.H.J |last4=Brown|first4=A.G.A |last5=Blaauw|first5=A. |date=1999|title=A HIPPARCOS Census of the Nearby OB Associations |journal=The Astronomical Journal |volume=117 |issue=1 |pages=354–399|bibcode=1999AJ....117..354D |doi=10.1086/300682|arxiv = astro-ph/9809227 |s2cid=16098861 }}</ref> Canopus is not thought to be a member of any nearby young stellar groups.<ref name=mamajek>{{cite journal | url=https://figshare.com/articles/Canopus_B_A_Candidate_Common_Proper_Motion_Companion_to_the_Second_Brightest_Star/1132696 | title=Canopus B: A Candidate Common Proper Motion Companion to the Second Brightest Star | last=Mamajek | first=Eric | year=2014 | publisher=Figshare | doi=10.6084/m9.figshare.1132696.v3 | access-date=2020-09-10 }}</ref> In 2014, astronomer Eric Mamajek reported that an extremely magnetically active M dwarf (having strong coronal X-ray emission), 1.16 degrees south of Canopus, appears to share a [[common proper motion]] with Canopus. The projected separation of the M dwarf 2MASS J06234738-5351131 ("Canopus B") is approximately 1.9 parsecs. However, despite this large separation, it is still within the estimated tidal radius (2.9 parsecs) for the massive star Canopus.<ref name="mamajek"/>
No star closer than Canopus is more luminous than it, and it has been the brightest star in Earth's night sky during three epochs over the past four million years. Other stars appear brighter only during relatively temporary periods, during which they are passing the Solar System much closer than Canopus. About 90,000 years ago, [[Sirius]] moved close enough that it became brighter than Canopus, and that will remain so for another 210,000 years. But in 480,000 years, as Sirius moves further away and appears fainter, Canopus will once again be the brightest, and will remain so for a period of about 510,000 years.<ref name="tomkin98">{{cite journal|last=Tomkin|first=Jocelyn|date=April 1998|title=Once and Future Celestial Kings|journal=Sky and Telescope|volume=95|issue=4|pages=59–63|bibcode=1998S&T....95d..59T}}</ref><!-- this all comes from same paper -->
===Role in navigation===
The southeastern wall of the [[Kaaba]] in [[Mecca]] is aligned with the rising point of Canopus, and is also named ''Janūb''.<ref>{{cite book|author=George Nicholas Atiyeh|title=The Book in the Islamic World: The Written Word and Communication in the Middle East|url=https://books.google.com/books?id=t4LEfpCW_kQC|date=1 January 1995|publisher=SUNY Press|isbn=978-0-7914-2473-5}}</ref> The [[Negev Bedouin|Bedouin]] people of the [[Negev]] and [[Sinai Peninsula|Sinai]] knew Canopus as ''Suhayl'', and used it and [[Polaris]] as the two principal stars for navigation at night. Because it disappears below the horizon in those regions, it became associated with a changeable nature, as opposed to always-visible Polaris, which was circumpolar and hence 'steadfast'.<ref>{{cite journal |last=Bailey |first=Clinton |date=1974 |title=Bedouin Star-Lore in Sinai and the Negev |journal=Bulletin of the School of Oriental and African Studies, University of London |volume=37 |issue=3 |pages=580–96 |type=abstract |doi=10.1017/S0041977X00127491 |jstor=613801|s2cid=131527348 }}</ref>
The south [[celestial pole]] can be approximately located using Canopus and another bright star, [[Achernar]], as the three make an [[equilateral triangle]]. Canopus sits on an imaginary line that extends {{DEC|36}} one way to Sirius and {{DEC|37}} to the south celestial pole.<ref>{{Cite book| last1 = Heifetz| first1 = Milton| last2 = Tirion| first2 = Wil| title = A Walk Through the Heavens: A Guide to Stars and Constellations and Their Legends | date = 2007| publisher = [[Cambridge University Press]]| location = Cambridge | page = 38 | isbn=978-1-139-46138-2}}</ref>
Canopus's brightness and location well off the [[ecliptic]] make it useful for space navigation. Many spacecraft carry a special camera known as a "Canopus [[star tracker|Star Tracker]]" plus a Sun sensor for [[Orientation (geometry)|attitude]] determination. [[Mariner 4]] used Canopus for [[Spin-stabilisation|second axis stabilisation]] (after locking on the Sun) in 1964, the first time a star had been used.<ref>{{cite book |last1=United States. National Aeronautics and Space Administration. Scientific and Technical Information Division |title=Astronautics and Aeronautics, 1964: Chronology on Science, Technology and Policy |date=1965 |publisher=Scientific and Technical Information Division, National Aeronautics and Space Administration |page=398 |url=https://books.google.com/books?id=ckkCAAAAIAAJ&pg=PA398}}</ref>
==Spectrum==
Canopus was little-studied by western scientists before the 20th century. It was given a spectral class of F in 1897, an early use of this extension to [[Secchi class]] I, applied to those stars where the hydrogen lines are relatively weak and the [[calcium K line]] relatively strong.<ref>{{cite journal |bibcode=1897ApJ.....6..349P |title=Spectra of bright southern stars |last1=Pickering |first1=E. C. |last2=Cannon |first2=A. J. |journal=The Astrophysical Journal |year=1897 |volume=6 |page=349 |doi=10.1086/140407 }}</ref> It was given as a standard star of F0 in the [[Henry Draper Catalogue]], with the spectral type F0 described as having hydrogen lines half the strength of an A0 star and the calcium K line three times as strong as Hδ.<ref name=hd>{{cite journal |bibcode=1918AnHar..92....1C |title=The Henry Draper catalogue : 4h, 5h and 6h |last1=Cannon |first1=Annie Jump |last2=Pickering |first2=Edward Charles |journal=Annals of Harvard College Observatory |year=1918 |volume=92 |page=1 }}</ref> American astronomer [[Jesse L. Greenstein|Jesse Greenstein]] was interested in stellar spectra and used the newly built [[Otto Struve Telescope]] at [[McDonald Observatory]] to analyze the star's spectrum in detail.<ref>{{cite book |last1=Trimble |first1=Virginia | first2= Thomas R. |last2=Williams | first3= Katherine | last3=Bracher| first4= Richard | last4=Jarrell| first5=Jordan D.| last5= Marché| first6=F. Jamil | last6=Ragep |title=Biographical Encyclopedia of Astronomers |date=2007 |publisher=Springer Science & Business Media |location=New York, New York |isbn=978-0-387-30400-7 |page=438 |url=https://books.google.com/books?id=t-BF1CHkc50C&pg=PA438}}</ref> In a 1942 paper, he reported that the spectrum is dominated by strong broad hydrogen lines. There are also [[absorption line]]s of carbon, nitrogen, oxygen, sulphur, iron, and many ionised metals.<ref name=greenstein1942>{{cite journal |bibcode=1942ApJ....95..161G |title=The Spectrum of α Carinae |last1=Greenstein |first1=Jesse L. |journal=The Astrophysical Journal |year=1942 |volume=95 |page=161 |doi=10.1086/144382 }}</ref> It was studied in the [[ultraviolet]] by an early astronomical satellite, [[Gemini XI]] in 1966. The UV spectra were considered to be consistent with an F0 [[Supergiant star|supergiant]] having a temperature of {{val|6,900|fmt=commas|u=K}}, the accepted parameters for Canopus at the time.<ref name=kondo1970>{{cite journal |bibcode=1970ApJ...159..927K |title=Ultraviolet Spectrophotometry of Canopus from Gemini XI |last1=Kondo |first1=Y. |last2=Henize |first2=K. G. |last3=Kotila |first3=C. L. |journal=The Astrophysical Journal |year=1970 |volume=159 |page=927 |doi=10.1086/150370 }}</ref> New Zealand-based astronomers [[John Hearnshaw]] and Krishna Desikachary examined the spectrum in greater detail, publishing their results in 1982.<ref>{{cite journal |title=The spectrum of Canopus | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 198 | year= 1982 | issue= 2 | pages= 311–320 | doi= 10.1093/mnras/198.2.311 | bibcode=1982MNRAS.198..311H| doi-access= free }}</ref><ref>{{cite journal |title=The spectrum of Canopus II - Analysis and composition | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 201 | year= 1982 | issue= 3 | pages= 707–721 | doi= 10.1093/mnras/201.3.707 | bibcode=1982MNRAS.201..707D| doi-access= free }}</ref>
When [[luminosity class]]es were added to the MK spectral classification scheme, Canopus was assigned class Iab indicating an intermediate luminosity supergiant. This was based on the relative strengths of certain spectral lines understood to be sensitive to the luminosity of a star.<ref name=devaucoleurs>{{cite journal|title=Spectral types and luminosities of B, A and F southern stars|author=de Vaucouleurs, A.|journal=Monthly Notices of the Royal Astronomical Society|volume=117|page=449|date=1957|issue=4|bibcode=1957MNRAS.117..449D|doi=10.1093/mnras/117.4.449|doi-access=free}}</ref> In the [[Bright Star Catalogue]] 5th edition it is given the spectral class F0II, the luminosity class indicating a [[bright giant]].<ref name=bsc>{{cite book |bibcode=1991bsc..book.....H |year=1991 |title=The Bright star catalogue |last1=Hoffleit |first1=Dorrit |last2=Jaschek |first2=Carlos }}</ref> [[Balmer line]] profiles and oxygen line strengths indicate the size and luminosity of Canopus.<ref name=kovtyukh2012>{{cite journal |bibcode=2012MNRAS.423.3268K |title=Accurate luminosities from the oxygen λ7771-4 Å triplet and the fundamental parameters of F-G supergiants |last1=Kovtyukh |first1=V. V. |last2=Gorlova |first2=N. I. |last3=Belik |first3=S. I. |journal=Monthly Notices of the Royal Astronomical Society |year=2012 |volume=423 |issue=4 |page=3268 |doi=10.1111/j.1365-2966.2012.21117.x |arxiv=1204.4115 |s2cid=118683158 }}</ref>
When the effects of stellar rotation speed on spectral lines are accounted for, the MK spectral class of Canopus is adjusted to A9II.<ref name=perkins/> Its spectrum consists mostly of absorption lines on a visible [[continuous spectrum|continuum]], but some emission has been detected. For example, the [[calcium K line]] have weak emission wings on each side of the strong central absorption line, first observed in 1966. The emission line profiles are usually correlated with the luminosity of the star as described by the [[Wilson-Bappu effect]], but in the case of Canopus they indicate a luminosity much lower than that calculated by other methods.<ref name=warner1966>{{cite journal|title=CA II emission in the spectrum of Canopus|journal=The Observatory |volume=86 |pages=82|date=April 1966|last=Warner |first=B. |bibcode=1966Obs....86...82W }}</ref> More detailed observations have shown that the emission line profiles are variable and may be due to [[plage (astronomy)|plage]] areas on the surface of the star. Emission can also be found in other lines such as the h and k lines of ionised magnesium.<ref name=bappu1984>{{cite journal |bibcode=1984BASI...12..196B |title=CA II K emission in Canopus |last1=Bappu |first1=M. K. V. |last2=Mekkaden |first2=M. V. |last3=Rao |first3=N. K. |journal=Bulletin of the Astronomical Society of India |year=1984 |volume=12 |page=196 }}</ref>
==Distance==
Before the launch of the [[Hipparcos]] satellite telescope, distance estimates for Canopus varied widely, from 96 [[light-year]]s to 1200 light-years. The closer distance was derived from parallax measurements of around {{val|33|ul=mas}}.<ref name=vandekamp1943>{{cite journal |title=Note on the Parallax of Canopus|journal=Popular Astronomy |volume=51 |date=1943 |page=172 |last=van de Kamp |first=Peter|bibcode=1943PA.....51..172V }}</ref> The larger distance derives from the assumption of a very bright [[absolute magnitude]] for Canopus.<ref name=vanzyl>{{cite book|author=J.E. van Zyl|title=Unveiling the Universe: An Introduction to Astronomy|url=https://books.google.com/books?id=Cj7uBwAAQBAJ&pg=PA184|date=6 December 2012|publisher=Springer Science & Business Media|isbn=978-1-4471-1037-8|pages=184–}}</ref>
Hipparcos established Canopus as being {{val|310|u=light-years}} ({{val|95|ul=parsecs}}) from the [[Solar System]]; this is based on its 2007 [[parallax]] measurement of {{Val|10.43|0.53|ul=mas}}.<ref name="van Leeuwen2007"/> At 95 parsecs, the [[interstellar extinction]] for Canopus is low at 0.26 magnitudes.<ref name=DomicianoDeSouza/> Canopus is too bright to be included in the normal observation runs of the [[Gaia satellite]] and there is no published Gaia parallax for it.<ref name=dr2>{{cite DR2}}</ref>
At present the star is drifting further away from the Sun with a [[radial velocity]] of 20 km/s. Some 3.1 million years ago it made the closest approach to the Sun at a distance of about {{convert|52.87|pc|ly|0|adj=ri0|order=flip|abbr=on|lk=off}}. Canopus is orbiting the Milky Way with a heliocentric velocity of 24.5 km/s and a low [[orbital eccentricity|eccentricity]] of 0.065.<ref name=Anderson2012>{{citation | last1=Anderson | first1=E. | last2=Francis | first2=Ch. | title=XHIP: An extended hipparcos compilation | journal=Astronomy Letters | volume=38 | issue=5 | pages=331 | year=2012 | bibcode=2012AstL...38..331A | arxiv=1108.4971 | doi=10.1134/S1063773712050015 | s2cid=119257644 | postscript=. }}</ref>
==Physical characteristics==
[[File:Constellation_Carina.jpg|thumb|right|upright|Canopus is the brightest star in the constellation of Carina (top).]]
The [[absorption line]]s in the spectrum of Canopus shift slightly with a period of {{val|6.9|u=days}}. This was first detected in 1906 and the [[doppler effect|Doppler]] variations were interpreted as orbital motion.<ref name=curtis1907>{{cite journal |bibcode=1907PASP...19R.259C |title=The orbits of the spectroscopic binaries alpha Carinae, kappa Velorum, and alpha Pavonis |last1=Curtis |first1=H. D. |journal=Publications of the Astronomical Society of the Pacific |year=1907 |volume=19 |page=259 |doi=10.1086/121781 }}</ref> An orbit was even calculated, but no such companion exists and the small radial velocity changes are due to movements in the atmosphere of the star. The maximum observed [[radial velocities]] are only 0.7 to {{val|1.6|ul=km/s}}. Canopus also has a magnetic field that varies with the same period, detected by the [[Zeeman splitting]] of its spectral lines.<ref name=weiss1986>{{cite journal |bibcode=1986A&A...160..243W | title=The magnetic field of Canopus | last=Weiss | first=W. W. | journal= Astronomy and Astrophysics |volume= 160|pages= 243–250 | year=1986}}</ref> Canopus is bright at [[microwave]] wavelengths, one of the few F-class stars to be detected by radio.<ref name=gudel2002>{{cite journal |bibcode=2002ARA&A..40..217G |title=Stellar Radio Astronomy: Probing Stellar Atmospheres from Protostars to Giants |last1=Güdel |first1=Manuel |journal=Annual Review of Astronomy and Astrophysics |year=2002 |volume=40 |pages=217–261 |doi=10.1146/annurev.astro.40.060401.093806 |arxiv=astro-ph/0206436 |s2cid=53633983 }}</ref> The [[rotation period]] of the star is not accurately known, but may be over three hundred days.<ref name=Testa2004>{{cite journal | title=The Density of Coronal Plasma in Active Stellar Coronae | last1=Testa | first1=Paola | last2=Drake | first2=Jeremy J. | last3=Peres | first3=Giovanni | journal=The Astrophysical Journal | volume=617 | issue=1 | pages=508–530 | date=December 2004 | doi=10.1086/422355 | arxiv=astro-ph/0405019 | bibcode=2004ApJ...617..508T | s2cid=17532089 }}</ref> The [[projected rotational velocity]] has been measured at 9 km/s.<ref name=ayres2018/>
An early [[Interferometry|interferometric]] measurement of its [[angular diameter]] in 1968 gave a [[Limb darkening|limb-darkened]] value of {{val|6.86|ul=mas}}, close to the accepted modern value.<ref>{{cite journal |bibcode=1968ARA&A...6...13B |title=Measurement of Stellar Diameters |last1=Brown |first1=R. Hanbury |journal=Annual Review of Astronomy and Astrophysics |year=1968 |volume=6 |page=13 |doi=10.1146/annurev.aa.06.090168.000305 }}</ref> [[Very-long-baseline interferometry]] has been used to calculate Canopus' angular diameter at {{val|6.9|ul=mas}}. Combined with distance calculated from its Hipparcos parallax, this gives it a radius of 71 times [[Solar radius|that of the Sun]].<ref name=vlti/> If it were at the centre of the Solar System, it would extend 90% of the way to the orbit of [[Mercury (planet)|Mercury]].<ref name=Kalerstars>{{cite web|url=http://stars.astro.illinois.edu/sow/canopus.html|title=Canopus|last=Kaler|first=Jim|work=Stars|publisher=University of Illinois|access-date=8 July 2012|date=26 June 2009}}</ref> The radius and temperature relative to the Sun means that it is 10,700 times more luminous than the Sun, and its position in the [[H-R diagram]] relative to theoretical [[stellar evolution|evolutionary]] tracks means that it is {{Val|8.0|0.3}} times as massive as the Sun.<ref name=vlti/> Measurements of its shape find a 1.1° departure from spherical symmetry.<ref name=cruzalebes2015>{{cite journal |bibcode=2015MNRAS.446.3277C |title=Departure from centrosymmetry of red giants and supergiants measured with VLTI/AMBER |last1=Cruzalèbes |first1=P. |last2=Jorissen |first2=A. |last3=Chiavassa |first3=A. |last4=Paladini |first4=C. |last5=Rabbia |first5=Y. |last6=Spang |first6=A. |journal=Monthly Notices of the Royal Astronomical Society |year=2015 |volume=446 |issue=4 |page=3277 |doi=10.1093/mnras/stu2382 |doi-access=free }}</ref>
Canopus is a source of [[X-ray astronomy|X-rays]], which are probably produced by its corona, magnetically heated to several million [[Kelvin]]. The temperature has likely been stimulated by fast rotation combined with strong convection percolating through the star's outer layers.<ref name=ness>{{cite journal|bibcode=2004A&A...427..667N|title=On the sizes of stellar X-ray coronae|journal=Astronomy and Astrophysics|volume=427|issue=2|pages=667–683|last1=Ness|first1=J.-U.|last2=Güdel|first2=M.|last3=Schmitt|first3=J. H. M. M.|last4=Audard|first4=M.|last5=Telleschi|first5=A.|year=2004|doi=10.1051/0004-6361:20040504|arxiv = astro-ph/0407231 |s2cid=11468731}}</ref> The soft X-ray sub-coronal X-ray emission is much weaker than the hard X-ray coronal emission. The same behaviour has been measured in other F-class supergiants such as [[α Persei]] and is now believed to be a normal property of such stars.<ref name=ayres2018/>
== Evolution ==
The spectrum of Canopus indicates that it has exhausted its core hydrogen and [[stellar evolution|evolved]] away from the [[main sequence]], where it spent some 30 million years of its existence as a blue-white star <!-- source suggests B2V but may be too exact --> of around 10 solar masses.<ref>{{cite journal |last1=Peimbert |first1=M. |last2=Wallerstein | first2= G.| last3= Pilachowski | first3= C. A. |title=An upper limit for the deuterium abundance in Canopus |journal=Astronomy and Astrophysics |date=1981 |volume=104 |issue=1 |pages=72–74 | bibcode=1981A&A...104...72P}}</ref> The position of Canopus in the [[H–R diagram]] indicates that it is currently in the core-helium burning phase.<ref name=vlti/> It is an intermediate mass star that has left the [[red-giant branch]] before its core became [[degenerate matter|degenerate]] and is now in a [[blue loop]].<ref name=desouza>{{Cite journal | last1 = Domiciano De Souza | first1 = A. | last2 = Bendjoya | first2 = P. | last3 = Vakili | first3 = F. | last4 = Millour | first4 = F. | last5 = Petrov | first5 = R. G. | title = Diameter and photospheric structures of Canopus from AMBER/VLTI interferometry | doi = 10.1051/0004-6361:200810450 | journal = Astronomy and Astrophysics | volume = 489 | issue = 2 | pages = L5–L8 | year = 2008 |bibcode = 2008A&A...489L...5D | url = https://hal.archives-ouvertes.fr/hal-00316994/document | doi-access = free }}</ref> Models of stellar evolution in the blue loop phase show that the length of the blue loop is strongly affected by rotation and mixing effects inside the star. It is difficult to determine whether a star is currently evolving towards hotter temperature or returning to cooler temperatures, since the evolutionary tracks for stars with different masses overlap during the blue loops.<ref name=smiljanic2006>{{cite journal |bibcode=2006A&A...449..655S |title=CNO in evolved intermediate mass stars |last1=Smiljanic |first1=R. |last2=Barbuy |first2=B. |last3=De Medeiros |first3=J. R. |last4=Maeder |first4=A. |journal=Astronomy and Astrophysics |year=2006 |volume=449 |issue=2 |page=655 |doi=10.1051/0004-6361:20054377 |arxiv=astro-ph/0511329 |s2cid=3711409 }}</ref>
Canopus lies on the warm side of the [[instability strip]] and does not pulsate like [[Cepheid variables]] of a similar luminosity.<ref name=ayres2011>{{cite journal |doi=10.1088/0004-637X/738/2/120 |title=The Curious Case of the Alpha Persei Corona: A Dwarf in Supergiant's Clothing? |year=2011 |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |volume=738 |issue=2 |page=120 |bibcode=2011ApJ...738..120A |doi-access=free }}</ref> However its atmosphere does appear to be unstable, showing strong signs of convection.<ref name=smiljanic2006/>
Canopus may not be massive enough for its [[nuclear fusion|fusion]] chain to reach iron and trigger a core collapse and subsequent [[supernova]], instead eventually becoming a neon-oxygen [[white dwarf]].<ref name=Kalerstars/>
==Cultural significance ==
Canopus was known to the ancient Mesopotamians and given the name ''NUN-ki'' and represented the city of [[Eridu]] in the ''Three Stars Each'' [[Babylonian star catalogues]] and later [[MUL.APIN]] around 1100 BC.<ref>{{cite journal | last = Rogers | first = John H. | date = 1998 | title = Origins of the Ancient Constellations: I. The Mesopotamian Traditions | journal = Journal of the British Astronomical Association | volume = 108 | issue = 1 | pages = 9–28 | bibcode = 1998JBAA..108....9R}}</ref> Today, the star [[Sigma Sagittarii]] is known by the common name Nunki.<ref name=allen>{{citation | page=359 | first1=Richard Hinckley | last1=Allen | title=Star Names, their lore and meaning}}</ref>
Canopus was not visible to the mainland [[Ancient Greece|ancient Greeks]] and [[Roman Empire|Romans]]; it was, however, visible to the [[ancient Egypt]]ians.<ref name="Schaaf107">Schaaf, p. 107.</ref> Hence [[Aratus]] did not write of the star as it remained below the horizon, while [[Eratosthenes]] and [[Ptolemy]]—observing from [[Alexandria]]—did, calling it ''Kanōbos''.<ref name=ridpathCr>{{cite web| url=http://www.ianridpath.com/startales/carina.htm | title=Carina |last1=Ridpath|first1=Ian|publisher=self-published |work=Star Tales | access-date= 10 December 2015}}</ref> An [[Egypt]]ian priestly poet in the time of [[Thutmose III]] mentions the star as ''Karbana,'' "the star which pours his light in a glance of fire, when he disperses the morning dew."<ref name="hinkley63" /> Under the [[Ptolemies]], the star was known as ''Ptolemaion'' ([[Ancient Greek|Greek]]: Πτολεμαῖον) and its [[acronychal rising]] marked the date of the Ptolemaia festival, which was held every four years, from 262 to 145 BC.<ref>[[Martianus Capella]] 7.838, {{cite journal | last1 = Hazzard | last2 = Fitzgerald | year = 1991 | title = The Regulation of the Ptolemeia | journal = Journal of the Royal Astronomical Society of Canada | volume = 85 | pages = 6–23 |bibcode = 1991JRASC..85....6H }}; Hazzard. 2000. ''Imagination of a Monarchy: Studies in Ptolemaic Propaganda'', 34–36.</ref>
[[File:Statue of Averroes in Córdoba, Spain.jpg|thumb|upright|[[Averroes]], who used his 1153 observation of Canopus in [[Marrakesh]] while the star was invisible in his native Spain as an argument that the [[Spherical Earth|earth is round]].<ref name=ibn_rushd/>]]
===India===
In Indian [[Vedas|Vedic literature]], Canopus is associated with the sage [[Agastya]], one of the ancient [[siddhar]]s and [[rishi]]s (the others are associated with the stars of the [[Big Dipper]]).<ref name="Frawley 1993">{{cite book|last=Frawley|first=David|title=Gods, Sages and Kings: Vedic Secrets of Ancient Civilization|publisher=Motilal Banarsidass |location=New Delhi, India|date=1993}}</ref> To Agastya, the star is said to be the 'cleanser of waters', and its rising coincides with the calming of the waters of the [[Indian Ocean]]. It is thus considered the son of [[Pulastya]], son of [[Brahma]]. Canopus is described by [[Pliny the Elder]] and [[Gaius Julius Solinus]] as the largest, brightest and only source of [[starlight]] for navigators near [[Tamraparni]] island (ancient Sri Lanka) during many nights.<ref>{{cite book |last1=Pridham |first1=Charles |title=An Historical, Political, and Statistical Account of Ceylon and Its Dependencies |date=1849 |publisher=T. and W. Boone |page=7 |url=https://books.google.com/books?id=O4aqHOMSJdYC&pg=PR19-IA5|language=en}}</ref><ref name="Frawley 1993"/><ref>{{cite book |last1=Elder |first1=Pliny the |title=Delphi Complete Works of Pliny the Elder (Illustrated) |date=2015 |publisher=Delphi Classics |url=https://books.google.com/books?id=OrJ0CgAAQBAJ&pg=PA343|language=en}}</ref>
===China===
Canopus was described as Shou Xing, the Star of Longevity, in the ''Shiji'' ([[Records of the Grand Historian]]) completed in 94 BC by Chinese historian [[Sima Qian]].<ref name=fong83>{{cite journal | title=The Iconography of the Popular Gods of Happiness, Emolument, and Longevity (Fu Lu Shou) | first=Mary H. |last=Fong | journal=Artibus Asiae | volume= 44 | issue= 2/3 | year=1983| pages= 159–199 | doi= 10.2307/3249596| jstor=3249596 }}</ref> Drawing on sources from the [[Warring States period]], he noted it to be the southern counterpart of [[Sirius]],<ref name="IDP"/> and wrote of a sanctuary dedicated to it established by Emperor [[Qin Shi Huang]] between 221 and 210 BC. During the [[Han dynasty]], the star was auspicious, its appearance in the southern sky heralding peace and absence war.<ref name=fong83/> From the imperial capital [[Chang'an]], the star made a low transit across the southern sky, indicating true south to observers, and was often obscured by clouds.<ref name=baumann19>{{cite journal | title=The White Old Man: Géluk-Mongolian Canopus Allegory and the Existence of God | first=Brian | last=Baumann | journal= Central Asiatic Journal | volume= 62 | issue= 1 | year=2019| pages= 35–68 | doi=10.13173/centasiaj.62.1.0035| s2cid=213083544 }}</ref> During this time it was also equated with [[Old Man of the South Pole]] (in {{zh|c=南极老人|p=Nanji Lǎorén}})<ref name=fong83/> Under this name, Canopus appears (albeit misplaced northwards) on the medieval Chinese manuscript the [[Dunhuang Star Chart]], although it cannot be seen from the Chinese capital of [[Chang'an]].<ref name="IDP">{{cite journal|bibcode=2009JAHH...12...39B|arxiv=0906.3034|title=The Dunhuang Sky: A Comprehensive Study of the Oldest Known Star Atlas|volume=12|issue=1|pages=39–59|last1=Bonnet-Bidaud|first1=Jean-Marc |last2=Praderie|first2=Françoise |last3=Whitfield|first3=Susan |author-link=Susan Whitfield |journal=The International Dunhuang Project: The Silk Road Online|year=2009}}</ref> The Chinese astronomer [[Yi Xing]] had journeyed south to chart Canopus and other far southern stars in 724 AD.<ref>{{cite book|last=Needham|first=Joseph|title=Science and Civilisation in China: Volume 3, Mathematics and the Sciences of the Heavens and the Earth|publisher=Cambridge University Press|location=Cambridge, United Kingdom|date=1959|pages=274|isbn=0521058015}}</ref> Its personification as the Old Man Star was popularised in the [[Tang Dynasty]], where it appeared often in poetry and memorials. Later still, during the [[Ming Dynasty]], the star was established as one of the [[Sanxing (deities)|Three Stars]] (Fu Lo Shou), appearing frequently in art and literature of the time.<ref name=fong83/> This symbolism spread into neighbouring cultures in Asia.<ref name=baumann19/>
In Japan, Canopus is known as ''Mera-boshi'' and ''Roujin-sei'' (the old man star),<ref>{{cite conference |url=http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |title=Stellar Iconology and Astronomical Folklore in Japan |author=Takao Ibaraki |book-title=International Planetarium Society (IPS) Conferences 1996 |publisher=International Planetarium Society |location=Osaka |date=14 July 1996 |access-date=25 February 2012 |url-status=dead |archive-url=https://web.archive.org/web/20120326195757/http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |archive-date=2012-03-26 }}</ref> and in Mongolia, it was personified as the White Old Man.<ref name=fong83/> Although the link was known in Tibet, with names such as ''Genpo karpo'' (''Rgan po dkar po'') or ''Genkar'' (''Rgan dkar'') "White Old Man", the symbolism was not popular. Instead, Canopus was more commonly named ''Karma Rishi སྐར་མ་རི་ཥི།'', derived from Indian mythology. Tibetans celebrated the star's heliacal rising with ritual bathing and associated it with morning dew.<ref name=baumann19/>
===Polynesia===
Bright stars were important to the ancient [[Polynesian culture|Polynesians]] for navigation between the many islands and atolls of the Pacific Ocean. Low on the horizon, they acted as stellar compasses to assist mariners in charting courses to particular destinations. Canopus served as the southern wingtip of a "Great Bird" constellation called ''Manu'', with Sirius as the body and [[Procyon]] the northern wingtip, which divided the Polynesian night sky into two hemispheres.<ref name="Holberg">{{cite book | last=Holberg | first=J.B. | title=Sirius: Brightest Diamond in the Night Sky | date=2007 | publisher=Praxis Publishing | location=Chichester, UK | isbn=978-0-387-48941-4 | pages=[https://archive.org/details/siriusbrightestd0000holb/page/25 25–26] | url=https://archive.org/details/siriusbrightestd0000holb/page/25 }}</ref> The [[Hawaiian people]] called Canopus ''Ke Alii-o-kona-i-ka-lewa'', "The chief of the southern expanse"; it was one of the stars used by [[Hawaiʻiloa]] and Ki when they traveled to the [[Southern Ocean]].{{sfn|Makemson|1941|p=198}} The [[Māori people]] of [[New Zealand|New Zealand/Aotearoa]] had several names for Canopus. ''[[Ariki]]'' ("High-born"), was known as a solitary star that appeared in the east, prompting people to weep and chant.{{sfn|Makemson|1941|p=201}} They also named it ''[[Atutahi]]'', ''Aotahi'' or ''Atuatahi'', "Stand Alone".<ref>p. 419, [https://books.google.com/books?id=p7dR2w1Wv2sC ''Mythology: Myths, Legends and Fantasies''], Janet Parker, Alice Mills, Julie Stanton, Durban, Struik Publishers, 2007.</ref> Its solitary nature indicates it is a ''[[Tapu (Polynesian culture)|tapu]]'' star, as ''tapu'' people are often solitary. Its appearance at the beginning of the ''Maruaroa'' season foretells the coming winter; light rays to the south indicate a cold wet winter, and to the north foretell a mild winter. Food was offered to the star on its appearance.<ref name="Best22">{{cite book|last=Best|first=Elsdon|title=Astronomical Knowledge of the Maori: Genuine and Empirical|publisher=Dominion Museum|location=Wellington, New Zealand|date=1922|pages=34–35|url=http://nzetc.victoria.ac.nz/tm/scholarly/tei-BesAstro-t1-body-d1-d6-d4.html}}</ref> This name has several mythologies attached to it. One story tells of how Atutahi was left outside the basket representing the [[Milky Way]] when [[Tāne]] wove it. Another related myth about the star says that Atutahi was the first-born child of [[Rangi and Papa|Rangi]], who refused to enter the Milky Way and so turned it sideways and rose before it. The same name is used for other stars and constellations throughout Polynesia.{{sfn|Makemson|1941|pp=200–202}} ''Kapae-poto'', "Short horizon", referred to it rarely setting as seen in New Zealand;{{sfn|Makemson|1941|p=217}} ''Kauanga'' ("Solitary") was the name for Canopus only when it was the last star visible before sunrise.{{sfn|Makemson|1941|p=218}} The people of the [[Society Islands]] had two names for Canopus, as did the [[Tuamotu]] people. The Society Islanders called Canopus ''Taurua-e-tupu-tai-nanu'', "Festivity-whence-comes-the-flux-of-the-sea", and ''Taurua-nui-o-te-hiti-apatoa'' "Great-festivity-of-the-border-of-the-south",{{sfn|Makemson|1941|p=259}} and the Tuamotu people called the star ''Te Tau-rari'' and ''Marere-te-tavahi'', the latter said to be the true name for the former, "He-who-stands-alone".{{sfn|Makemson|1941|p=229}}
===Africa===
In the [[Guanches|Guanche]] mythology of the island of [[Tenerife]] (Spain), the star Canopus was linked with the goddess [[Chaxiraxi]].<ref name="Rumeu">{{cite book|author=Antonio Rumeu de Armas|title=La conquista de Tenerife, 1494–1496|url=https://books.google.com/books?id=Ck4BAAAAMAAJ|year=1975|publisher=Aula de Cultura de Tenerife|isbn=9788450071078}}</ref>
The [[Tswana people]] of [[Botswana]] knew Canopus as ''Naka''. Appearing late in winter skies, it heralded increasing winds and a time when trees lose their leaves. Stock owners knew it was time to put their sheep with rams.<ref>{{cite journal|last=Clegg|first=Andrew|date=1986|title=Some Aspects of Tswana Cosmology|journal=Botswana Notes and Records|volume=18|pages=33–37|jstor=40979758 }}</ref> In southern Africa, the Sotho, Tswana and Venda people called Canopus ''Naka'' or ''Nanga'', “the Horn Star”, while the Zulu and Swazi called it ''inKhwenkwezi'' "Brilliant star". It appears in the predawn sky in the third week of May. According to the Venda, the first person to see Canopus would blow a ''phalaphala'' horn from the top of a hill, getting a cow for a reward. The Sotho chiefs also awarded a cow, and ordered their medicine men to roll bone dice and read the fortune for the coming year.<ref name=snedegar95>{{cite journal |last1=Snedegar |first1=K.V. |title=Stars and seasons in Southern Africa |journal=Vistas in Astronomy |date=1995 |volume=39 |issue=4 |pages=529–38 |doi=10.1016/0083-6656(95)00008-9|bibcode=1995VA.....39..529S }}</ref> To the [[ǀXam language|ǀXam]]-speaking [[Bushmen]] of South Africa, Canopus and Sirius signalled the appearance of termites and flying ants. They also believed that stars had the power to cause death and misfortune, and they would pray to [[Sirius]] and Canopus in particular to impart good fortune or skill.<ref>{{cite journal| title="The Sky's Things", <nowiki>|</nowiki>xam Bushman 'Astrological Mythology' as recorded in the Bleek and Lloyd Manuscripts |last1=Hollman|first1=J. C.|journal=African Sky|volume= 11|page=8 |bibcode=2007AfrSk..11....8H|year = 2007 }}</ref> The [[ǃKung people]] of the [[Kalahari Desert]] in Botswana held Canopus and Capella to be the horns of ''tshxum'' (the Pleiades), the appearance of all three marking the end of the dry season and start of the rainy season.<ref>{{cite journal |last1=Marshall |first1=Lorna |title=Two Ju/ wa constellations |journal=Botswana Notes & Records |date=1975 |volume=7 |issue=1 |pages=153–159 | issn=0525-5090 |url=https://journals.co.za/docserver/fulltext/botnotes/7/1/548.pdf?expires=1590793041&id=id&accname=guest&checksum=3204085F9555AD9D083799E1F38E3AED}}</ref>
===Americas===
The [[Navajo]] observed the star and named it ''Maʼii Bizòʼ'', the “Coyote Star”. According to legend, Maʼii (Coyote) took part in the naming and placing of the star constellations during
the creation of the universe. He placed Canopus directly south, naming it after himself.<ref name="Maryboy">Maryboy, Nancy D. (2004). ''A Guide to Navajo Astronomy.'' Indigenous Education Institute : Bluff, Utah.</ref>
The [[Kalapalo]] people of [[Mato Grosso]] state in Brazil saw Canopus and [[Procyon]] as ''Kofongo'' "Duck", with [[Castor (star)|Castor]] and [[Pollux (star)|Pollux]] representing his hands. The asterism's appearance signified the coming of the rainy season and increase in [[manioc]], a food staple fed to guests at feasts.<ref name="basso87">{{cite book|last=Basso|first=Ellen B. |title=In Favor of Deceit: A Study of Tricksters in an Amazonian Society|publisher=University of Arizona Press|location=Tucson, Arizona|date=1987|page=[https://archive.org/details/infavorofdeceits0000bass/page/360 360]|isbn=0816510229|url=https://archive.org/details/infavorofdeceits0000bass|url-access=registration}}</ref>
===Australia===
Canopus is identified as the moiety ancestor ''Waa'' "Crow" to some [[Koori]] people in southeastern Australia.<ref>{{cite book|last=Mudrooroo|title=Aboriginal mythology: an A-Z spanning the history of aboriginal mythology from the earliest legends to the present day|publisher=HarperCollins|location=London|date=1994|page=27|isbn=1-85538-306-3}}</ref> The Boorong people of northwestern Victoria recalled that ''War'' (Canopus) was the brother of ''Warepil'' (Sirius), and that he brought fire from the heavens and introduced it to humanity. His wife was ''Collowgullouric War'' ([[Eta Carinae]]).<ref name=hamacher10>{{cite journal|last1=Hamacher|first1=Duane W. |last2=Frew|first2=David J. |date=2010|title= An Aboriginal Australian Record of the Great Eruption of Eta Carinae|journal=Journal of Astronomical History & Heritage |volume=13|issue=3|pages= 220–34|bibcode=2010JAHH...13..220H|arxiv = 1010.4610 }}</ref> The Pirt-Kopan-noot people of western Victoria tell of ''Waa'' "Crow" falling in love with a queen, ''Gneeanggar'' "Wedge-tailed Eagle" (Sirius) and her six attendants (the Pleiades). His advances spurned, he hears that the women are foraging for grubs and so transforms himself into a grub. When the women dig him out, he changes into a giant and carries her off.<ref>Mudroodoo, p. 55.</ref>
The Kulin people know Canopus as ''Lo-an-tuka''.<ref name=hamacher10/> Objects in the sky are also associated with states of being for some tribes; the Wailwun of northern New South Wales know Canopus as ''Wumba'' "deaf", alongside Mars as ''Gumba'' "fat" and Venus as ''Ngindigindoer'' "you are laughing".<ref name="noctuary">{{cite book|last=Johnson|first=Diane|title=Night skies of aboriginal Australia: a noctuary|publisher=University of Sydney|location=Darlington, New South Wales|date=1998|page=[https://archive.org/details/nightskiesofabor0000john/page/84 84]|isbn=1-86451-356-X|url-access=registration|url=https://archive.org/details/nightskiesofabor0000john/page/84}}</ref> Tasmanian aboriginal lore holds that Canopus is ''Dromerdene'', the brother of ''Moinee''; the two fought and fell out of the sky, with ''Dromerdene'' falling into Louisa Bay in southwest Tasmania.<ref name="haynes2000">{{cite book|last=Haynes|first=Ros D.|title= Astronomy and the Dreaming: The Astronomy of the Aboriginal Australians. Astronomy Across Cultures: The History of Non-Western Astronomy|publisher=Kluwer Academic Publishers|date=2000|page=57|doi=10.1007/978-94-011-4179-6_3}}</ref>
===Legacy===
[[File:HMS Glory LOC ggbain.17135.jpg|thumb|right|[[Canopus-class battleship]] HMS Glory]]
Canopus appears on the [[flag of Brazil]], symbolising the state of [[Goiás]].<ref>{{cite web
|title=Astronomy of the Brazilian Flag
|url=https://flagspot.net/flags/br_astro.html
|publisher=FOTW Flags Of The World website
}}</ref>
Two U.S. Navy [[submarine tender]]s have been named after Canopus, the [[USS Canopus (AS-9)|first]] serving from 1922 to 1942 and the [[USS Canopus (AS-34)|second]] serving from 1965 to 1994.
The [[Royal Navy]] built nine [[Canopus-class ship of the line|Canopus-class ships of the line]] in the early 19th century, and six {{Sclass|Canopus|battleship|1}}s which entered services between 1899 and 1902.
There are at least two mountains named after the star: [[Mount Canopus]] in Antarctica; and Mount Canopus or Canopus Hill in [[Tasmania]], the location of the [[Canopus Hill Observatory|Canopus Hill astronomical observatory]].
{{clear}}
==See also==
*[[List of brightest stars]]
*[[List of most luminous stars]]
*[[Dune (novel)]]
==References==
{{Reflist|30em}}
===Bibliography===
* {{cite book | last = Makemson | first = Maud Worcester | date = 1941 | publisher = [[Yale University Press]] | title = The Morning Star Rises: an account of Polynesian astronomy | bibcode = 1941msra.book.....M }}
* {{cite book |title=The Brightest Stars: Discovering the Universe through the Sky's Most Brilliant Stars |last=Schaaf |first=Fred |year=2008 |publisher=John Wiley & Sons |location=Hoboken, NJ |isbn=978-0-471-70410-2 }}
== External links ==
{{Sky|06|23|57.1099|-|52|41|44.378|310}}
{{Carina (constellation)}}
{{Portal bar|Astronomy|Stars|Spaceflight|Outer space|Solar System}}
{{Authority control}}
{{DEFAULTSORT:Canopus}}
[[Category:Canopus| ]]
[[Category:Bayer objects|Carinae, Alpha]]
[[Category:Carina (constellation)]]
[[Category:A-type bright giants]]
[[Category:Henry Draper Catalogue objects|045348]]
[[Category:Hipparcos objects|030438]]
[[Category:Bright Star Catalogue objects|2326]]
[[Category:Stars with proper names]]
[[Category:Durchmusterung objects]]
3547233edddd3de1b6a9882514b6f145cc63ca57
Module:Val/units
828
45
105
2022-09-01T19:37:59Z
Canopus >BD2412
0
KB [[Kilobyte|KB]] 8e3
Scribunto
text/plain
-- Definitions for units known to val
-- File format is two strings and a return statement with them in it:
-- string in quotes [=[ ... builtin_units ... ]=].
-- string in quotes [=[ ... builtin_units_long_scale ... ]=].
-- First string, builtin_units, is short-scale, second string is long scale.
-- Entry format:
-- One record per line, starting in first column, having 2-4 fields.
-- Field separator: two or more spaces
-- Between first and second fields: two or more spaces
-- Between all other fields: two or more spaces, or one or more tabs
-- Entries without two spaces in them are ignored.
-- There must be a blank line before the first entry and after the last.
-- I.e. the first two and last two characters of the string must be newlines.
-- Format of entry. Two record types:
--
-- One record type is a wikilink:
-- Unit-code [[ pagename | Symbol-accepts-HTML-only ]]
-- Text-field separator is still two spaces. Two spaces not allowed in wikilink.
--
-- The other record type is all fields:
-- Unit-code symbol-accepts-HTML-only pagename#section-OK
--
-- Plus there is an optional field that goes at the end after two or more spaces.
-- Whether it is a number or an equation or the letters SI,
-- any of these three has the same function: a wikitable sorting "scale".
-- It is for sorting, and it works for either record type.
-- Difference is SI can't accept HTML. But SI correctly scales any SI prefix.
-- (Optional fields ALIAS and NOSPACE and ANGLE are for advanced users.)
-- "Invalid unit" error:
-- Using SI requires that the symbol equal unit-code, so never allows HTML.
-- Any difference between SI or symbol must be an SI prefix, such as k, M, or G.
-- A space at the end of an entry is an error. No space at each EOL.
local builtin_units = [=[
== Test ==
Foo [[Hz|<samp>Foo</samp>]]
Baz [[Hertz|baz<sub>0</sub>]]
Baz [[Kelvins|baz<sub>0</sub>]]
Bar [[Foobar|bar<abbr title="super duper">0</abbr>]]
quux [[Foobar|<span title="super duper 2">bar0</span>]]
== Unsorted units ==
c0 [[Speed of light#Numerical value, notation, and units|''c''<sub>0</sub>]]
lbf [[Pound (force)|<span title="pound-force">lb<sub>F</sub></span> ]]
N.s [[Newton-second|N⋅s]]
J.K-1 [[Joule per kelvin|J⋅K<sup>−1</sup>]]
C.mol-1 [[Faraday constant|C⋅mol<sup>−1</sup>]]
C/mol [[Faraday constant|C/mol]]
C.kg-1 [[Roentgen (unit)|C⋅kg<sup>−1</sup>]]
C/kg [[Roentgen (unit)|C/kg]]
F.m-1 [[vacuum permittivity|F⋅m<sup>−1</sup>]]
F/m [[vacuum permittivity|F/m]]
e [[Elementary charge|''e'']]
kB [[Kilobyte|kB]] 8e3
KB [[Kilobyte|KB]] 8e3
MB [[Megabyte|MB]] 8e6
GB [[Gigabyte|GB]] 8e9
TB [[Terabyte|TB]] 8e12
lx [[Lux (unit)|lx]]
nat [[nat (unit)|nat]]
== Time and frequency ==
byte/s [[Data rate units|byte/s]] 8
kB/s [[Data rate units#Kilobyte per second|<span title="Kilobytes per second">kB/s</span>]] 8e3
MB/s [[Data rate units#Megabyte per second|<span title="Megabytes per second">MB/s</span>]] 8e6
GB/s [[Data rate units#Gigabyte per second|<span title="Gigabytes per second">GB/s</span>]] 8e9
TB/s [[Data rate units#Terabyte per second|<span title="Terabytes per second">TB/s</span>]] 8e12
bit/s [[Bit per second|bit/s]] 1
bps [[Bit per second|bit/s]] 1
kbit/s [[Kilobit per second|kbit/s]] 1e3
Mbit/s [[Megabit per second|Mbit/s]] 1e6
Gbit/s [[Gigabit per second|Gbit/s]] 1e9
Tbit/s [[Terabit per second|Tbit/s]] 1e12
kT/s [[Transfer (computing)|<span title="Kilotransfers per second">kT/s</span>]] 1e3
MT/s [[Transfer (computing)|<span title="Megatransfers per second">MT/s</span>]] 1e6
GT/s [[Transfer (computing)|<span title="Gigatransfers per second">GT/s</span>]] 1e9
year [[Year|year]] 31557600
years [[Year|years]] 31557600
yr [[Year#Symbols y and yr|yr]] 31557600
y [[Year|y]] 31557600
a [[Annum|a]] 31557600
Ga [[Gigaannum|Ga]] 31557600000000000
Ma [[Megaannum|Ma]] 31557600000000
ka [[Kiloannum|ka]] 31557600000
kyr [[kyr|kyr]] 31557600000
kya [[kyr|kya]] 31557600000
myr [[myr|myr]] 31557600000000
mya [[Mya (unit)|mya]] 31557600000000
byr [[Billion years|byr]] 31557600000000000
bya [[Billion years ago|bya]] 31557600000000000
Gyr [[billion years|Gyr]] 31557600000000000
BP [[Before present|BP]]
uBP [[Radiocarbon dating#Calibration|<sup>14</sup>C yr BP]]
BC [[Before Christ|BC]] -1
AD [[Anno Domini|AD]] 1
BCE [[Before the Common Era|BCE]] -1
CE [[Common Era|CE]] 1
JD [[Julian date|JD]] 1
MJD [[Modified Julian date|MJD]] 1
s-1 [[Second|s<sup>−1</sup>]]
s-2 [[Second|s<sup>−2</sup>]]
s2 [[Second|s<sup>2</sup>]]
s [[Second|s]] SI
as [[Attosecond|s]] SI
cs [[Second|s]] SI
das [[Second|s]] SI
ds [[Second|s]] SI
Es [[Second|s]] SI
fs [[Femtosecond|s]] SI
Gs [[Second|s]] SI
hs [[Second|s]] SI
ks [[Second|s]] SI
ms [[Millisecond|s]] SI
µs [[Microsecond|s]] SI
us [[Microsecond|s]] SI
Ms [[Second|s]] SI
ns [[Nanosecond|s]] SI
ps [[Picosecond|s]] SI
Ps [[Second|s]] SI
Ts [[Second|s]] SI
Ys [[Second|s]] SI
ys [[Yoctosecond|s]] SI
Zs [[Second|s]] SI
zs [[Zeptosecond|s]] SI
Hz [[Hertz|Hz]] SI
aHz [[Hertz|Hz]] SI
cHz [[Hertz|Hz]] SI
daHz [[Hertz|Hz]] SI
dHz [[Hertz|Hz]] SI
EHz [[Hertz|Hz]] SI
fHz [[Hertz|Hz]] SI
hHz [[Hertz|Hz]] SI
GHz [[Gigahertz|Hz]] SI
kHz [[Kilohertz|Hz]] SI
MHz [[Megahertz|Hz]] SI
mHz [[Hertz|Hz]] SI
uHz [[Hertz|Hz]] SI
µHz [[Hertz|Hz]] SI
nHz [[Hertz|Hz]] SI
pHz [[Hertz|Hz]] SI
PHz [[Hertz|Hz]] SI
THz [[Hertz|Hz]] SI
yHz [[Hertz|Hz]] SI
YHz [[Hertz|Hz]] SI
zHz [[Hertz|Hz]] SI
ZHz [[Hertz|Hz]] SI
ips [[Inch per second|ips]]
== Length, area, volume ==
Å3 [[Ångström|Å<sup>3</sup>]]
fb-1 [[Barn (unit)|fb<sup>−1</sup>]]
m-1 [[Metre|m<sup>−1</sup>]]
m-2 [[Square metre|m<sup>−2</sup>]]
m-3 [[Cubic metre|m<sup>−3</sup>]]
km2 [[Square kilometre|km<sup>2</sup>]]
km3 [[Cubic kilometre|km<sup>3</sup>]]
µm2 [[Square metre|µm<sup>2</sup>]]
um2 [[Square metre|µm<sup>2</sup>]]
am2 [[Square metre|am<sup>2</sup>]]
cm2 [[Square centimetre|cm<sup>2</sup>]]
dam2 [[Square metre|dam<sup>2</sup>]]
dm2 [[Square metre|dm<sup>2</sup>]]
Em2 [[Square metre|Em<sup>2</sup>]]
fm2 [[Square metre|fm<sup>2</sup>]]
Gm2 [[Square metre|Gm<sup>2</sup>]]
hm2 [[Square metre|hm<sup>2</sup>]]
mm2 [[Square metre|mm<sup>2</sup>]]
Mm2 [[Square metre|Mm<sup>2</sup>]]
nm2 [[Square metre|nm<sup>2</sup>]]
pm2 [[Square metre|pm<sup>2</sup>]]
Pm2 [[Square metre|Pm<sup>2</sup>]]
Tm2 [[Square metre|Tm<sup>2</sup>]]
ym2 [[Square metre|ym<sup>2</sup>]]
Ym2 [[Square metre|Ym<sup>2</sup>]]
zm2 [[Square metre|zm<sup>2</sup>]]
Zm2 [[Square metre|Zm<sup>2</sup>]]
gal [[Gallon|gal]]
Gal [[Gal (unit)|Gal]]
uGal [[Gal (unit)|µGal]]
µGal [[Gal (unit)|µGal]]
mGal [[Gal (unit)|mGal]]
b [[Barn (unit)|b]] SI
ab [[Barn (unit)|b]] SI
cb [[Barn (unit)|b]] SI
dab [[Barn (unit)|b]] SI
db [[Barn (unit)|b]] SI
Eb [[Barn (unit)|b]] SI
fb [[Barn (unit)|b]] SI
Gb [[Barn (unit)|b]] SI
hb [[Barn (unit)|b]] SI
kb [[Barn (unit)|b]] SI
mb [[Barn (unit)|b]] SI
µb [[Barn (unit)|b]] SI
ub [[Barn (unit)|b]] SI
Mb [[Barn (unit)|b]] SI
nb [[Barn (unit)|b]] SI
pb [[Barn (unit)|b]] SI
Pb [[Barn (unit)|b]] SI
Tb [[Barn (unit)|b]] SI
Yb [[Barn (unit)|b]] SI
yb [[Barn (unit)|b]] SI
Zb [[Barn (unit)|b]] SI
zb [[Barn (unit)|b]] SI
== Velocity and acceleration ==
m.s-2 [[Metre per second squared|m⋅s<sup>−2</sup>]]
m/s2 [[Metre per second squared|m/s<sup>2</sup>]]
m.s-1 [[Metre per second|m⋅s<sup>−1</sup>]]
m/s [[Metre per second|m/s]]
km.s-1 [[Metre per second|km⋅s<sup>−1</sup>]]
km/s [[Metre per second|km/s]]
== Mass and energy ==
lbm [[Pound (mass)|<span title="pound-mass">lb<sub>m</sub></span>]]
uJ [[Joule|µJ]]
J.s [[Joule-second|J⋅s]]
kWh [[Kilowatt hour|kWh]]
kW.h [[Kilowatt hour|kW⋅h]]
J/C [[Volt|J/C]]
J/kg [[Joule|J/kg]]
Da [[Dalton (unit)|Da]] SI
EDa [[Dalton (unit)|Da]] SI
PDa [[Dalton (unit)|Da]] SI
TDa [[Dalton (unit)|Da]] SI
GDa [[Dalton (unit)|Da]] SI
MDa [[Dalton (unit)|Da]] SI
kDa [[Dalton (unit)|Da]] SI
mDa [[Dalton (unit)|Da]] SI
uDa [[Dalton (unit)|Da]] SI
μDa [[Dalton (unit)|Da]] SI
nDa [[Dalton (unit)|Da]] SI
pDa [[Dalton (unit)|Da]] SI
fDa [[Dalton (unit)|Da]] SI
aDa [[Dalton (unit)|Da]] SI
g [[Gram|g]] SI
ag [[Attogram|g]] SI
cg [[Centigram|g]] SI
dag [[Gram|g]] SI
dg [[Decigram|g]] SI
Eg [[Exagram|g]] SI
fg [[Femtogram|g]] SI
Gg [[Gigagram|g]] SI
hg [[Kilogram#SI multiples|g]] SI
kg [[Kilogram|g]] SI
mcg [[Microgram|g]] SI
Mg [[Megagram|g]] SI
mg [[Milligram|g]] SI
ug [[Microgram|g]] SI
µg [[Microgram|g]] SI
ng [[Nanogram|g]] SI
Pg [[Petagram|g]] SI
pg [[Picogram|g]] SI
Tg [[Tonne|g]] SI
yg [[Yoctogram|g]] SI
Yg [[Yottagram|g]] SI
zg [[Zeptogram|g]] SI
Zg [[Zettagram|g]] SI
== Pressure and density ==
psi [[Pounds per square inch|psi]]
g.cm-3 [[Gram per cubic centimetre|g⋅cm<sup>−3</sup>]]
g/cm3 [[Gram per cubic centimetre|g/cm<sup>3</sup>]]
kg.m-3 [[Kilogram per cubic metre|kg⋅m<sup>−3</sup>]]
kg/m3 [[Kilogram per cubic metre|kg/m<sup>3</sup>]]
kg/cm3 [[Density#Formula and common units|kg/cm<sup>3</sup>]]
g/L [[Gram per litre|g/L]]
g/l [[Gram per litre|g/l]]
mcg/dL [[Gram per litre|µg/dL]]
mcg/dl [[Gram per litre|µg/dl]]
mg/mL [[Gram per litre|mg/mL]]
mg/ml [[Gram per litre|mg/ml]]
ug/dL [[Gram per litre|µg/dL]]
ug/dl [[Gram per litre|µg/dl]]
μg/dL [[Gram per litre|μg/dL]]
μg/dl [[Gram per litre|μg/dl]]
mg.L-1 [[Gram per litre|<abbr title="milligrams per liter">mg/L</abbr>]]
mg/L [[Gram per litre|<abbr title="milligrams per liter">mg/L</abbr>]]
mg.l-1 [[Gram per litre|<abbr title="milligrams per liter">mg/l</abbr>]]
mg/l [[Gram per litre|<abbr title="milligrams per liter">mg/l</abbr>]]
== Fracture toughness ==
MPa.m.5 [[Fracture toughness|MPa⋅m<sup>1/2</sup>]]
kPa.m.5 [[Fracture toughness|kPa⋅m<sup>1/2</sup>]]
Pa.m.5 [[Fracture toughness|Pa⋅m<sup>1/2</sup>]]
== Temperature ==
degC °C ALIAS
degF °F ALIAS
degR °R ALIAS
K [[Kelvin|K]] SI
YK [[Yottakelvin|K]] SI
ZK [[Zettakelvin|K]] SI
EK [[Kelvin|K]] SI
PK [[Petakelvin|K]] SI
TK [[Terakelvin|K]] SI
GK [[Gigakelvin|K]] SI
MK [[Megakelvin|K]] SI
kK [[Kilokelvin|K]] SI
hK [[Hectokelvin|K]] SI
daK [[Decakelvin|K]] SI
dK [[Decikelvin|K]] SI
cK [[Centikelvin|K]] SI
mK [[Millikelvin|K]] SI
µK [[Microkelvin|K]] SI
uK [[Microkelvin|K]] SI
nK [[Nanokelvin|K]] SI
pK [[Picokelvin|K]] SI
fK [[Femtokelvin|K]] SI
aK [[Attokelvin|K]] SI
zK [[Zeptokelvin|K]] SI
yK [[Yoctokelvin|K]] SI
== Electromagnetism ==
Wb [[Weber (unit)|Wb]]
N.A-2 [[Permeability (electromagnetism)|N⋅A<sup>−2</sup>]]
H.m-1 [[Permeability (electromagnetism)|H⋅m<sup>−1</sup>]]
V.m-1 [[Electric field|V⋅m<sup>−1</sup>]]
V/m [[Electric field|V/m]]
C [[Coulomb|C]] SI
YC [[Coulomb|C]] SI
ZC [[Coulomb|C]] SI
EC [[Coulomb|C]] SI
PC [[Coulomb|C]] SI
TC [[Coulomb|C]] SI
GC [[Coulomb|C]] SI
MC [[Coulomb|C]] SI
kC [[Coulomb|C]] SI
hC [[Coulomb|C]] SI
daC [[Coulomb|C]] SI
dC [[Coulomb|C]] SI
cC [[Coulomb|C]] SI
mC [[Coulomb|C]] SI
µC [[Coulomb|C]] SI
uC [[Coulomb|C]] SI
nC [[Coulomb|C]] SI
pC [[Coulomb|C]] SI
fC [[Coulomb|C]] SI
aC [[Coulomb|C]] SI
zC [[Coulomb|C]] SI
yC [[Coulomb|C]] SI
F [[Farad|F]] SI
YF [[Farad|F]] SI
ZF [[Farad|F]] SI
EF [[Farad|F]] SI
PF [[Farad|F]] SI
TF [[Farad|F]] SI
GF [[Farad|F]] SI
MF [[Farad|F]] SI
kF [[Farad|F]] SI
hF [[Farad|F]] SI
daF [[Farad|F]] SI
dF [[Farad|F]] SI
cF [[Farad|F]] SI
mF [[Farad|F]] SI
µF [[Farad|F]] SI
uF [[Farad|F]] SI
nF [[Farad|F]] SI
pF [[Farad|F]] SI
fF [[Farad|F]] SI
aF [[Farad|F]] SI
zF [[Farad|F]] SI
yF [[Farad|F]] SI
H [[Henry (unit)|H]] SI
YH [[Henry (unit)|H]] SI
ZH [[Henry (unit)|H]] SI
EH [[Henry (unit)|H]] SI
PH [[Henry (unit)|H]] SI
TH [[Henry (unit)|H]] SI
GH [[Henry (unit)|H]] SI
MH [[Henry (unit)|H]] SI
kH [[Henry (unit)|H]] SI
hH [[Henry (unit)|H]] SI
daH [[Henry (unit)|H]] SI
dH [[Henry (unit)|H]] SI
cH [[Henry (unit)|H]] SI
mH [[Henry (unit)|H]] SI
µH [[Henry (unit)|H]] SI
uH [[Henry (unit)|H]] SI
nH [[Henry (unit)|H]] SI
pH [[Henry (unit)|H]] SI
fH [[Henry (unit)|H]] SI
aH [[Henry (unit)|H]] SI
zH [[Henry (unit)|H]] SI
yH [[Henry (unit)|H]] SI
A [[Ampere|A]] SI
YA [[Ampere|A]] SI
ZA [[Ampere|A]] SI
EA [[Ampere|A]] SI
PA [[Ampere|A]] SI
TA [[Ampere|A]] SI
GA [[Ampere|A]] SI
MA [[Ampere|A]] SI
kA [[Ampere|A]] SI
hA [[Ampere|A]] SI
daA [[Ampere|A]] SI
dA [[Ampere|A]] SI
cA [[Ampere|A]] SI
mA [[Ampere|A]] SI
µA [[Ampere|A]] SI
uA [[Ampere|A]] SI
nA [[Ampere|A]] SI
pA [[Ampere|A]] SI
fA [[Ampere|A]] SI
aA [[Ampere|A]] SI
zA [[Ampere|A]] SI
yA [[Ampere|A]] SI
V [[Volt|V]] SI
YV [[Volt|V]] SI
ZV [[Volt|V]] SI
EV [[Volt|V]] SI
PV [[Volt|V]] SI
TV [[Volt|V]] SI
GV [[Volt|V]] SI
MV [[Volt|V]] SI
kV [[Volt|V]] SI
hV [[Volt|V]] SI
daV [[Volt|V]] SI
dV [[Volt|V]] SI
cV [[Volt|V]] SI
mV [[Volt|V]] SI
µV [[Volt|V]] SI
uV [[Volt|V]] SI
nV [[Volt|V]] SI
pV [[Volt|V]] SI
fV [[Volt|V]] SI
aV [[Volt|V]] SI
zV [[Volt|V]] SI
yV [[Volt|V]] SI
VA [[Volt-ampere|VA]] SI
YVA [[Volt-ampere|VA]] SI
ZVA [[Volt-ampere|VA]] SI
EVA [[Volt-ampere|VA]] SI
PVA [[Volt-ampere|VA]] SI
TVA [[Volt-ampere|VA]] SI
GVA [[Volt-ampere|VA]] SI
MVA [[Volt-ampere|VA]] SI
kVA [[Volt-ampere|VA]] SI
hVA [[Volt-ampere|VA]] SI
daVA [[Volt-ampere|VA]] SI
dVA [[Volt-ampere|VA]] SI
cVA [[Volt-ampere|VA]] SI
mVA [[Volt-ampere|VA]] SI
µVA [[Volt-ampere|VA]] SI
uVA [[Volt-ampere|VA]] SI
nVA [[Volt-ampere|VA]] SI
pVA [[Volt-ampere|VA]] SI
fVA [[Volt-ampere|VA]] SI
aVA [[Volt-ampere|VA]] SI
zVA [[Volt-ampere|VA]] SI
yVA [[Volt-ampere|VA]] SI
Ω [[Ohm|Ω]] SI
YΩ.m [[Electrical resistivity and conductivity#Definition|YΩ⋅m]] 1e24
ZΩ.m [[Electrical resistivity and conductivity#Definition|ZΩ⋅m]] 1e21
EΩ.m [[Electrical resistivity and conductivity#Definition|EΩ⋅m]] 1e18
PΩ.m [[Electrical resistivity and conductivity#Definition|PΩ⋅m]] 1e15
TΩ.m [[Electrical resistivity and conductivity#Definition|TΩ⋅m]] 1e12
GΩ.m [[Electrical resistivity and conductivity#Definition|GΩ⋅m]] 1e9
MΩ.m [[Electrical resistivity and conductivity#Definition|MΩ⋅m]] 1e6
kΩ.m [[Electrical resistivity and conductivity#Definition|kΩ⋅m]] 1e3
Ω.m [[Electrical resistivity and conductivity#Definition|Ω⋅m]] 1
mΩ.m [[Electrical resistivity and conductivity#Definition|mΩ⋅m]] 1e-3
µΩ.m [[Electrical resistivity and conductivity#Definition|µΩ⋅m]] 1e-6
uΩ.m [[Electrical resistivity and conductivity#Definition|µΩ⋅m]] 1e-6
nΩ.m [[Electrical resistivity and conductivity#Definition|nΩ⋅m]] 1e-9
pΩ.m [[Electrical resistivity and conductivity#Definition|pΩ⋅m]] 1e-12
fΩ.m [[Electrical resistivity and conductivity#Definition|fΩ⋅m]] 1e-15
aΩ.m [[Electrical resistivity and conductivity#Definition|aΩ⋅m]] 1e-18
zΩ.m [[Electrical resistivity and conductivity#Definition|zΩ⋅m]] 1e-21
yΩ.m [[Electrical resistivity and conductivity#Definition|yΩ⋅m]] 1e-24
R [[Rayleigh (unit)|R]] SI
G [[Gauss (unit)|G]] SI
aG [[Attogauss|G]] SI
cG [[Centigauss|G]] SI
daG [[Decagauss|G]] SI
dG [[Decigauss|G]] SI
EG [[Exagauss|G]] SI
fG [[Femtogauss|G]] SI
GG [[Gigagauss|G]] SI
hG [[Hectogauss|G]] SI
kG [[Kilogauss|G]] SI
MG [[Megagauss|G]] SI
mG [[Milligauss|G]] SI
uG [[Microgauss|G]] SI
µG [[Microgauss|G]] SI
nG [[Nanogauss|G]] SI
PG [[Petagauss|G]] SI
pG [[Picogauss|G]] SI
TG [[Teragauss|G]] SI
yG [[Yoctogauss|G]] SI
YG [[Yottagauss|G]] SI
zG [[Zeptogauss|G]] SI
ZG [[Zettagauss|G]] SI
T [[Tesla (unit)|T]] SI
aT [[Attotesla|T]] SI
cT [[Centitesla|T]] SI
daT [[Decatesla|T]] SI
dT [[Decitesla|T]] SI
ET [[Exatesla|T]] SI
fT [[Femtotesla|T]] SI
GT [[Gigatesla|T]] SI
hT [[Hectotesla|T]] SI
kT [[Kilotesla|T]] SI
MT [[Megatesla|T]] SI
mT [[Millitesla|T]] SI
uT [[Microtesla|T]] SI
µT [[Microtesla|T]] SI
nT [[Nanotesla|T]] SI
PT [[Petatesla|T]] SI
pT [[Picotesla|T]] SI
TT [[Teratesla|T]] SI
yT [[Yoctotesla|T]] SI
YT [[Yottatesla|T]] SI
zT [[Zeptotesla|T]] SI
ZT [[Zettatesla|T]] SI
== Astrophysics ==
au [[Astronomical unit|au]]
c [[Speed of light|''c'']]
ly [[Light-year|ly]]
dex [[decimal exponent|dex]]
Earth mass [[Earth mass|''M''<sub>🜨</sub>]]
Earth radius [[Earth radius|''R''<sub>🜨</sub>]]
M_Earth [[Earth mass|''M''<sub>🜨</sub>]]
R_Earth [[Earth radius|''R''<sub>🜨</sub>]]
M+ [[Earth mass|''M''<sub>🜨</sub>]]
R+ [[Earth radius|''R''<sub>🜨</sub>]]
Jupiter mass [[Jupiter mass|''M''<sub>J</sub>]]
Jupiter radius [[Jupiter radius|''R''<sub>J</sub>]]
M_Jupiter [[Jupiter mass|''M''<sub>J</sub>]]
R_Jupiter [[Jupiter radius|''R''<sub>J</sub>]]
Solar mass [[Solar mass|''M''<sub>☉</sub>]]
solar mass [[Solar mass|''M''<sub>☉</sub>]]
M_Solar [[Solar mass|''M''<sub>☉</sub>]]
M_solar [[Solar mass|''M''<sub>☉</sub>]]
R_Solar [[Solar radius|''R''<sub>☉</sub>]]
R_solar [[Solar radius|''R''<sub>☉</sub>]]
Solar radius [[Solar radius|''R''<sub>☉</sub>]]
solar radius [[Solar radius|''R''<sub>☉</sub>]]
Solar luminosity [[Solar luminosity|''L''<sub>☉</sub>]]
solar luminosity [[Solar luminosity|''L''<sub>☉</sub>]]
L_solar [[Solar luminosity|''L''<sub>☉</sub>]]
L_Solar [[Solar luminosity|''L''<sub>☉</sub>]]
Lo [[Solar luminosity|''L''<sub>☉</sub>]]
pc2 [[Parsec|pc<sup>2</sup>]]
pc3 [[Parsec|pc<sup>3</sup>]]
kpc2 [[Parsec#Parsecs and kiloparsecs|kpc<sup>2</sup>]]
kpc3 [[Parsec#Parsecs and kiloparsecs|kpc<sup>3</sup>]]
kpc [[Parsec#Parsecs and kiloparsecs|kpc]]
Mpc2 [[Parsec#Megaparsecs and gigaparsecs|Mpc<sup>2</sup>]]
Mpc3 [[Parsec#Megaparsecs and gigaparsecs|Mpc<sup>3</sup>]]
Mpc [[Parsec#Megaparsecs and gigaparsecs|Mpc]]
Gpc2 [[Parsec#Megaparsecs and gigaparsecs|Gpc<sup>2</sup>]]
Gpc3 [[Parsec#Megaparsecs and gigaparsecs|Gpc<sup>3</sup>]]
Gpc [[Parsec#Megaparsecs and gigaparsecs|Gpc]]
== Nuclear physics and chemistry ==
cm-1 [[Wavenumber|cm<sup>−1</sup>]]
u [[Unified atomic mass unit|u]]
osmol [[Osmole (unit)|osmol]]
Osm [[Osmole (unit)|Osm]]
M [[Molarity|M]]
TM [[Molarity|M]] SI
GM [[Molarity|M]] SI
MM [[Molarity|M]] SI
kM [[Molarity|M]] SI
hM [[Molarity|M]] SI
daM [[Molarity|M]] SI
dM [[Molarity|M]] SI
cM [[Molarity|M]] SI
mM [[Molarity|M]] SI
uM [[Molarity|M]] 1e-6
nM [[Molarity|M]] SI
pM [[Molarity|M]] SI
kg.mol-1 [[Molar mass|kg⋅mol<sup>−1</sup>]]
kg/mol [[Molar mass|kg/mol]]
g.mol-1 [[Molar mass|g⋅mol<sup>−1</sup>]]
g/mol [[Molar mass|g/mol]]
eV/c2 [[Electronvolt#Mass|eV/''c''<sup>2</sup>]]
keV/c2 [[Electronvolt#Mass|keV/''c''<sup>2</sup>]]
MeV/c2 [[Electronvolt#Mass|MeV/''c''<sup>2</sup>]]
GeV/c2 [[Electronvolt#Mass|GeV/''c''<sup>2</sup>]]
TeV/c2 [[Electronvolt#Mass|TeV/''c''<sup>2</sup>]]
eV [[Electronvolt|eV]]
meV [[Electronvolt|meV]]
keV [[Electronvolt|keV]]
MeV [[Electronvolt|MeV]]
GeV [[Electronvolt|GeV]]
TeV [[Electronvolt|TeV]]
mol-1 [[Avogadro constant|mol<sup>−1</sup>]]
J.mol-1 [[Joule per mole|J⋅mol<sup>−1</sup>]]
J/mol [[Joule per mole|J/mol]]
kJ.mol-1 [[Joule per mole|kJ⋅mol<sup>−1</sup>]]
kJ/mol [[Joule per mole|kJ/mol]]
MJ.mol-1 [[Joule per mole|MJ⋅mol<sup>−1</sup>]]
MJ/mol [[Joule per mole|MJ/mol]]
GJ.mol-1 [[Joule per mole|GJ⋅mol<sup>−1</sup>]]
GJ/mol [[Joule per mole|GJ/mol]]
TJ.mol-1 [[Joule per mole|TJ⋅mol<sup>−1</sup>]]
TJ/mol [[Joule per mole|TJ/mol]]
== Numbers and phrases ==
pp [[Page (paper)|pp]]
ppb [[Parts per billion|ppb]] 1e-9
ppm [[Parts per million|ppm]] 1e-6
billiard [[Orders of magnitude (numbers)#1015|billiard]] 1e15
billion [[1,000,000,000|billion]] 1e9
billionth [[1,000,000,000|billionth]] 1e-9
billionths [[1,000,000,000|billionths]] 1e-9
decilliard [[Orders of magnitude (numbers)#1063|decilliard]] 1e63
decillion [[Orders of magnitude (numbers)#1033|decillion]] 1e33
decillionth [[Orders of magnitude (numbers)#1033|decillionth]] 1e-33
decillionths [[Orders of magnitude (numbers)#1033|decillionths]] 1e-33
milliard [[1,000,000,000|milliard]] 1e9
million [[Million|million]] 1e6
millionth [[Million|millionth]] 1e-6
millionths [[Million|millionths]] 1e-6
nonilliard [[Orders of magnitude (numbers)#1057|nonilliard]] 1e57
nonillion [[Orders of magnitude (numbers)#1030|nonillion]] 1e30
nonillionth [[Orders of magnitude (numbers)#1030|nonillionth]] 1e-30
nonillionths [[Orders of magnitude (numbers)#1030|nonillionths]] 1e-30
octilliard [[Orders of magnitude (numbers)#1051|octilliard]] 1e51
octillion [[Orders of magnitude (numbers)#1027|octillion]] 1e27
octillionth [[Orders of magnitude (numbers)#1027|octillionth]] 1e-27
octillionths [[Orders of magnitude (numbers)#1027|octillionths]] 1e-27
quadrilliard [[Orders of magnitude (numbers)#1027|quadrilliard]] 1e27
quadrillion [[Orders of magnitude (numbers)#1015|quadrillion]] 1e15
quadrillionth [[Orders of magnitude (numbers)#1015|quadrillionth]] 1e-15
quadrillionths [[Orders of magnitude (numbers)#1015|quadrillionths]] 1e-15
quintilliard [[Orders of magnitude (numbers)#1033|quintilliard]] 1e33
quintillion [[Orders of magnitude (numbers)#1018|quintillion]] 1e18
quintillionth [[Orders of magnitude (numbers)#1018|quintillionth]] 1e-18
quintillionths [[Orders of magnitude (numbers)#1018|quintillionths]] 1e-18
septilliard [[Orders of magnitude (numbers)#1045|septilliard]] 1e45
septillion [[Orders of magnitude (numbers)#1024|septillion]] 1e24
septillionth [[Orders of magnitude (numbers)#1024|septillionth]] 1e-24
septillionths [[Orders of magnitude (numbers)#1024|septillionths]] 1e-24
sextilliard [[Orders of magnitude (numbers)#1039|sextilliard]] 1e39
sextillion [[Orders of magnitude (numbers)#1021|sextillion]] 1e21
sextillionth [[Orders of magnitude (numbers)#1021|sextillionth]] 1e-21
sextillionths [[Orders of magnitude (numbers)#1021|sextillionths]] 1e-21
trilliard [[Orders of magnitude (numbers)#1021|trilliard]] 1e21
trillion [[Orders of magnitude (numbers)#1012|trillion]] 1e12
trillionth [[Orders of magnitude (numbers)#1012|trillionth]] 1e-12
trillionths [[Orders of magnitude (numbers)#1012|trillionths]] 1e-12
== Angles ==
% % Percent ANGLE 0.01
percent % Percent ANGLE 0.01
per cent % Percent ANGLE 0.01
‰ ‰ Per mil ANGLE 1e-3
per mil ‰ Per mil ANGLE 1e-3
per mill ‰ Per mil ANGLE 1e-3
per mille ‰ Per mil ANGLE 1e-3
permil ‰ Per mil ANGLE 1e-3
permill ‰ Per mil ANGLE 1e-3
permille ‰ Per mil ANGLE 1e-3
° ° Degree (angle) ANGLE pi/180
deg ° Degree (angle) ANGLE pi/180
' ′ Minute of arc ANGLE pi/10800
′ ′ Minute of arc ANGLE pi/10800
arcmin ′ Minute of arc ANGLE pi/10800
arcminute ′ Minute of arc ANGLE pi/10800
" ″ Second of arc ANGLE pi/648000
″ ″ Second of arc ANGLE pi/648000
arcsec ″ Second of arc ANGLE pi/648000
arcsecond ″ Second of arc ANGLE pi/648000
mas [[Milliarcsecond|mas]] pi/648000000
]=]
-- If val has "|long scale=on" the following definitions are used
-- (then, if not found here, the normal definitions are used).
-- Unit code [[Link|Symbol]] Flags/Scale
local builtin_units_long_scale = [=[
== Long scale numbers and phrases ==
billion [[Orders of magnitude (numbers)#1012|billion]] 1e12
billionth [[Orders of magnitude (numbers)#1012|billionth]] 1e-12
billionths [[Orders of magnitude (numbers)#1012|billionths]] 1e-12
decillion [[Orders of magnitude (numbers)#1060|decillion]] 1e60
decillionth [[Orders of magnitude (numbers)#1060|decillionth]] 1e-60
decillionths [[Orders of magnitude (numbers)#1060|decillionths]] 1e-60
nonillion [[Orders of magnitude (numbers)#1054|nonillion]] 1e54
nonillionth [[Orders of magnitude (numbers)#1054|nonillionth]] 1e-54
nonillionths [[Orders of magnitude (numbers)#1054|nonillionths]] 1e-54
octillion [[Orders of magnitude (numbers)#1048|octillion]] 1e48
octillionth [[Orders of magnitude (numbers)#1048|octillionth]] 1e-48
octillionths [[Orders of magnitude (numbers)#1048|octillionths]] 1e-48
quadrillion [[Orders of magnitude (numbers)#1024|quadrillion]] 1e24
quadrillionth [[Orders of magnitude (numbers)#1024|quadrillionth]] 1e-24
quadrillionths [[Orders of magnitude (numbers)#1024|quadrillionths]] 1e-24
quintillion [[Orders of magnitude (numbers)#1030|quintillion]] 1e30
quintillionth [[Orders of magnitude (numbers)#1030|quintillionth]] 1e-30
quintillionths [[Orders of magnitude (numbers)#1030|quintillionths]] 1e-30
septillion [[Orders of magnitude (numbers)#1042|septillion]] 1e42
septillionth [[Orders of magnitude (numbers)#1042|septillionth]] 1e-42
septillionths [[Orders of magnitude (numbers)#1042|septillionths]] 1e-42
sextillion [[Orders of magnitude (numbers)#1036|sextillion]] 1e36
sextillionth [[Orders of magnitude (numbers)#1036|sextillionth]] 1e-36
sextillionths [[Orders of magnitude (numbers)#1036|sextillionths]] 1e-36
trillion [[Orders of magnitude (numbers)#1018|trillion]] 1e18
trillionth [[Orders of magnitude (numbers)#1018|trillionth]] 1e-18
trillionths [[Orders of magnitude (numbers)#1018|trillionths]] 1e-18
]=]
return { builtin_units = builtin_units, builtin_units_long_scale = builtin_units_long_scale }
81ae3510367fd477db8e031a5103f8a573b86138
106
105
2022-09-04T15:24:30Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- Definitions for units known to val
-- File format is two strings and a return statement with them in it:
-- string in quotes [=[ ... builtin_units ... ]=].
-- string in quotes [=[ ... builtin_units_long_scale ... ]=].
-- First string, builtin_units, is short-scale, second string is long scale.
-- Entry format:
-- One record per line, starting in first column, having 2-4 fields.
-- Field separator: two or more spaces
-- Between first and second fields: two or more spaces
-- Between all other fields: two or more spaces, or one or more tabs
-- Entries without two spaces in them are ignored.
-- There must be a blank line before the first entry and after the last.
-- I.e. the first two and last two characters of the string must be newlines.
-- Format of entry. Two record types:
--
-- One record type is a wikilink:
-- Unit-code [[ pagename | Symbol-accepts-HTML-only ]]
-- Text-field separator is still two spaces. Two spaces not allowed in wikilink.
--
-- The other record type is all fields:
-- Unit-code symbol-accepts-HTML-only pagename#section-OK
--
-- Plus there is an optional field that goes at the end after two or more spaces.
-- Whether it is a number or an equation or the letters SI,
-- any of these three has the same function: a wikitable sorting "scale".
-- It is for sorting, and it works for either record type.
-- Difference is SI can't accept HTML. But SI correctly scales any SI prefix.
-- (Optional fields ALIAS and NOSPACE and ANGLE are for advanced users.)
-- "Invalid unit" error:
-- Using SI requires that the symbol equal unit-code, so never allows HTML.
-- Any difference between SI or symbol must be an SI prefix, such as k, M, or G.
-- A space at the end of an entry is an error. No space at each EOL.
local builtin_units = [=[
== Test ==
Foo [[Hz|<samp>Foo</samp>]]
Baz [[Hertz|baz<sub>0</sub>]]
Baz [[Kelvins|baz<sub>0</sub>]]
Bar [[Foobar|bar<abbr title="super duper">0</abbr>]]
quux [[Foobar|<span title="super duper 2">bar0</span>]]
== Unsorted units ==
c0 [[Speed of light#Numerical value, notation, and units|''c''<sub>0</sub>]]
lbf [[Pound (force)|<span title="pound-force">lb<sub>F</sub></span> ]]
N.s [[Newton-second|N⋅s]]
J.K-1 [[Joule per kelvin|J⋅K<sup>−1</sup>]]
C.mol-1 [[Faraday constant|C⋅mol<sup>−1</sup>]]
C/mol [[Faraday constant|C/mol]]
C.kg-1 [[Roentgen (unit)|C⋅kg<sup>−1</sup>]]
C/kg [[Roentgen (unit)|C/kg]]
F.m-1 [[vacuum permittivity|F⋅m<sup>−1</sup>]]
F/m [[vacuum permittivity|F/m]]
e [[Elementary charge|''e'']]
kB [[Kilobyte|kB]] 8e3
KB [[Kilobyte|KB]] 8e3
MB [[Megabyte|MB]] 8e6
GB [[Gigabyte|GB]] 8e9
TB [[Terabyte|TB]] 8e12
lx [[Lux (unit)|lx]]
nat [[nat (unit)|nat]]
== Time and frequency ==
byte/s [[Data rate units|byte/s]] 8
kB/s [[Data rate units#Kilobyte per second|<span title="Kilobytes per second">kB/s</span>]] 8e3
MB/s [[Data rate units#Megabyte per second|<span title="Megabytes per second">MB/s</span>]] 8e6
GB/s [[Data rate units#Gigabyte per second|<span title="Gigabytes per second">GB/s</span>]] 8e9
TB/s [[Data rate units#Terabyte per second|<span title="Terabytes per second">TB/s</span>]] 8e12
bit/s [[Bit per second|bit/s]] 1
bps [[Bit per second|bit/s]] 1
kbit/s [[Kilobit per second|kbit/s]] 1e3
Mbit/s [[Megabit per second|Mbit/s]] 1e6
Gbit/s [[Gigabit per second|Gbit/s]] 1e9
Tbit/s [[Terabit per second|Tbit/s]] 1e12
kT/s [[Transfer (computing)|<span title="Kilotransfers per second">kT/s</span>]] 1e3
MT/s [[Transfer (computing)|<span title="Megatransfers per second">MT/s</span>]] 1e6
GT/s [[Transfer (computing)|<span title="Gigatransfers per second">GT/s</span>]] 1e9
year [[Year|year]] 31557600
years [[Year|years]] 31557600
yr [[Year#Symbols y and yr|yr]] 31557600
y [[Year|y]] 31557600
a [[Annum|a]] 31557600
Ga [[Gigaannum|Ga]] 31557600000000000
Ma [[Megaannum|Ma]] 31557600000000
ka [[Kiloannum|ka]] 31557600000
kyr [[kyr|kyr]] 31557600000
kya [[kyr|kya]] 31557600000
myr [[myr|myr]] 31557600000000
mya [[Mya (unit)|mya]] 31557600000000
byr [[Billion years|byr]] 31557600000000000
bya [[Billion years ago|bya]] 31557600000000000
Gyr [[billion years|Gyr]] 31557600000000000
BP [[Before present|BP]]
uBP [[Radiocarbon dating#Calibration|<sup>14</sup>C yr BP]]
BC [[Before Christ|BC]] -1
AD [[Anno Domini|AD]] 1
BCE [[Before the Common Era|BCE]] -1
CE [[Common Era|CE]] 1
JD [[Julian date|JD]] 1
MJD [[Modified Julian date|MJD]] 1
s-1 [[Second|s<sup>−1</sup>]]
s-2 [[Second|s<sup>−2</sup>]]
s2 [[Second|s<sup>2</sup>]]
s [[Second|s]] SI
as [[Attosecond|s]] SI
cs [[Second|s]] SI
das [[Second|s]] SI
ds [[Second|s]] SI
Es [[Second|s]] SI
fs [[Femtosecond|s]] SI
Gs [[Second|s]] SI
hs [[Second|s]] SI
ks [[Second|s]] SI
ms [[Millisecond|s]] SI
µs [[Microsecond|s]] SI
us [[Microsecond|s]] SI
Ms [[Second|s]] SI
ns [[Nanosecond|s]] SI
ps [[Picosecond|s]] SI
Ps [[Second|s]] SI
Ts [[Second|s]] SI
Ys [[Second|s]] SI
ys [[Yoctosecond|s]] SI
Zs [[Second|s]] SI
zs [[Zeptosecond|s]] SI
Hz [[Hertz|Hz]] SI
aHz [[Hertz|Hz]] SI
cHz [[Hertz|Hz]] SI
daHz [[Hertz|Hz]] SI
dHz [[Hertz|Hz]] SI
EHz [[Hertz|Hz]] SI
fHz [[Hertz|Hz]] SI
hHz [[Hertz|Hz]] SI
GHz [[Gigahertz|Hz]] SI
kHz [[Kilohertz|Hz]] SI
MHz [[Megahertz|Hz]] SI
mHz [[Hertz|Hz]] SI
uHz [[Hertz|Hz]] SI
µHz [[Hertz|Hz]] SI
nHz [[Hertz|Hz]] SI
pHz [[Hertz|Hz]] SI
PHz [[Hertz|Hz]] SI
THz [[Hertz|Hz]] SI
yHz [[Hertz|Hz]] SI
YHz [[Hertz|Hz]] SI
zHz [[Hertz|Hz]] SI
ZHz [[Hertz|Hz]] SI
ips [[Inch per second|ips]]
== Length, area, volume ==
Å3 [[Ångström|Å<sup>3</sup>]]
fb-1 [[Barn (unit)|fb<sup>−1</sup>]]
m-1 [[Metre|m<sup>−1</sup>]]
m-2 [[Square metre|m<sup>−2</sup>]]
m-3 [[Cubic metre|m<sup>−3</sup>]]
km2 [[Square kilometre|km<sup>2</sup>]]
km3 [[Cubic kilometre|km<sup>3</sup>]]
µm2 [[Square metre|µm<sup>2</sup>]]
um2 [[Square metre|µm<sup>2</sup>]]
am2 [[Square metre|am<sup>2</sup>]]
cm2 [[Square centimetre|cm<sup>2</sup>]]
dam2 [[Square metre|dam<sup>2</sup>]]
dm2 [[Square metre|dm<sup>2</sup>]]
Em2 [[Square metre|Em<sup>2</sup>]]
fm2 [[Square metre|fm<sup>2</sup>]]
Gm2 [[Square metre|Gm<sup>2</sup>]]
hm2 [[Square metre|hm<sup>2</sup>]]
mm2 [[Square metre|mm<sup>2</sup>]]
Mm2 [[Square metre|Mm<sup>2</sup>]]
nm2 [[Square metre|nm<sup>2</sup>]]
pm2 [[Square metre|pm<sup>2</sup>]]
Pm2 [[Square metre|Pm<sup>2</sup>]]
Tm2 [[Square metre|Tm<sup>2</sup>]]
ym2 [[Square metre|ym<sup>2</sup>]]
Ym2 [[Square metre|Ym<sup>2</sup>]]
zm2 [[Square metre|zm<sup>2</sup>]]
Zm2 [[Square metre|Zm<sup>2</sup>]]
gal [[Gallon|gal]]
Gal [[Gal (unit)|Gal]]
uGal [[Gal (unit)|µGal]]
µGal [[Gal (unit)|µGal]]
mGal [[Gal (unit)|mGal]]
b [[Barn (unit)|b]] SI
ab [[Barn (unit)|b]] SI
cb [[Barn (unit)|b]] SI
dab [[Barn (unit)|b]] SI
db [[Barn (unit)|b]] SI
Eb [[Barn (unit)|b]] SI
fb [[Barn (unit)|b]] SI
Gb [[Barn (unit)|b]] SI
hb [[Barn (unit)|b]] SI
kb [[Barn (unit)|b]] SI
mb [[Barn (unit)|b]] SI
µb [[Barn (unit)|b]] SI
ub [[Barn (unit)|b]] SI
Mb [[Barn (unit)|b]] SI
nb [[Barn (unit)|b]] SI
pb [[Barn (unit)|b]] SI
Pb [[Barn (unit)|b]] SI
Tb [[Barn (unit)|b]] SI
Yb [[Barn (unit)|b]] SI
yb [[Barn (unit)|b]] SI
Zb [[Barn (unit)|b]] SI
zb [[Barn (unit)|b]] SI
== Velocity and acceleration ==
m.s-2 [[Metre per second squared|m⋅s<sup>−2</sup>]]
m/s2 [[Metre per second squared|m/s<sup>2</sup>]]
m.s-1 [[Metre per second|m⋅s<sup>−1</sup>]]
m/s [[Metre per second|m/s]]
km.s-1 [[Metre per second|km⋅s<sup>−1</sup>]]
km/s [[Metre per second|km/s]]
== Mass and energy ==
lbm [[Pound (mass)|<span title="pound-mass">lb<sub>m</sub></span>]]
uJ [[Joule|µJ]]
J.s [[Joule-second|J⋅s]]
kWh [[Kilowatt hour|kWh]]
kW.h [[Kilowatt hour|kW⋅h]]
J/C [[Volt|J/C]]
J/kg [[Joule|J/kg]]
Da [[Dalton (unit)|Da]] SI
EDa [[Dalton (unit)|Da]] SI
PDa [[Dalton (unit)|Da]] SI
TDa [[Dalton (unit)|Da]] SI
GDa [[Dalton (unit)|Da]] SI
MDa [[Dalton (unit)|Da]] SI
kDa [[Dalton (unit)|Da]] SI
mDa [[Dalton (unit)|Da]] SI
uDa [[Dalton (unit)|Da]] SI
μDa [[Dalton (unit)|Da]] SI
nDa [[Dalton (unit)|Da]] SI
pDa [[Dalton (unit)|Da]] SI
fDa [[Dalton (unit)|Da]] SI
aDa [[Dalton (unit)|Da]] SI
g [[Gram|g]] SI
ag [[Attogram|g]] SI
cg [[Centigram|g]] SI
dag [[Gram|g]] SI
dg [[Decigram|g]] SI
Eg [[Exagram|g]] SI
fg [[Femtogram|g]] SI
Gg [[Gigagram|g]] SI
hg [[Kilogram#SI multiples|g]] SI
kg [[Kilogram|g]] SI
mcg [[Microgram|g]] SI
Mg [[Megagram|g]] SI
mg [[Milligram|g]] SI
ug [[Microgram|g]] SI
µg [[Microgram|g]] SI
ng [[Nanogram|g]] SI
Pg [[Petagram|g]] SI
pg [[Picogram|g]] SI
Tg [[Tonne|g]] SI
yg [[Yoctogram|g]] SI
Yg [[Yottagram|g]] SI
zg [[Zeptogram|g]] SI
Zg [[Zettagram|g]] SI
== Pressure and density ==
psi [[Pounds per square inch|psi]]
g.cm-3 [[Gram per cubic centimetre|g⋅cm<sup>−3</sup>]]
g/cm3 [[Gram per cubic centimetre|g/cm<sup>3</sup>]]
kg.m-3 [[Kilogram per cubic metre|kg⋅m<sup>−3</sup>]]
kg/m3 [[Kilogram per cubic metre|kg/m<sup>3</sup>]]
kg/cm3 [[Density#Formula and common units|kg/cm<sup>3</sup>]]
g/L [[Gram per litre|g/L]]
g/l [[Gram per litre|g/l]]
mcg/dL [[Gram per litre|µg/dL]]
mcg/dl [[Gram per litre|µg/dl]]
mg/mL [[Gram per litre|mg/mL]]
mg/ml [[Gram per litre|mg/ml]]
ug/dL [[Gram per litre|µg/dL]]
ug/dl [[Gram per litre|µg/dl]]
μg/dL [[Gram per litre|μg/dL]]
μg/dl [[Gram per litre|μg/dl]]
mg.L-1 [[Gram per litre|<abbr title="milligrams per liter">mg/L</abbr>]]
mg/L [[Gram per litre|<abbr title="milligrams per liter">mg/L</abbr>]]
mg.l-1 [[Gram per litre|<abbr title="milligrams per liter">mg/l</abbr>]]
mg/l [[Gram per litre|<abbr title="milligrams per liter">mg/l</abbr>]]
== Fracture toughness ==
MPa.m.5 [[Fracture toughness|MPa⋅m<sup>1/2</sup>]]
kPa.m.5 [[Fracture toughness|kPa⋅m<sup>1/2</sup>]]
Pa.m.5 [[Fracture toughness|Pa⋅m<sup>1/2</sup>]]
== Temperature ==
degC °C ALIAS
degF °F ALIAS
degR °R ALIAS
K [[Kelvin|K]] SI
YK [[Yottakelvin|K]] SI
ZK [[Zettakelvin|K]] SI
EK [[Kelvin|K]] SI
PK [[Petakelvin|K]] SI
TK [[Terakelvin|K]] SI
GK [[Gigakelvin|K]] SI
MK [[Megakelvin|K]] SI
kK [[Kilokelvin|K]] SI
hK [[Hectokelvin|K]] SI
daK [[Decakelvin|K]] SI
dK [[Decikelvin|K]] SI
cK [[Centikelvin|K]] SI
mK [[Millikelvin|K]] SI
µK [[Microkelvin|K]] SI
uK [[Microkelvin|K]] SI
nK [[Nanokelvin|K]] SI
pK [[Picokelvin|K]] SI
fK [[Femtokelvin|K]] SI
aK [[Attokelvin|K]] SI
zK [[Zeptokelvin|K]] SI
yK [[Yoctokelvin|K]] SI
== Electromagnetism ==
Wb [[Weber (unit)|Wb]]
N.A-2 [[Permeability (electromagnetism)|N⋅A<sup>−2</sup>]]
H.m-1 [[Permeability (electromagnetism)|H⋅m<sup>−1</sup>]]
V.m-1 [[Electric field|V⋅m<sup>−1</sup>]]
V/m [[Electric field|V/m]]
C [[Coulomb|C]] SI
YC [[Coulomb|C]] SI
ZC [[Coulomb|C]] SI
EC [[Coulomb|C]] SI
PC [[Coulomb|C]] SI
TC [[Coulomb|C]] SI
GC [[Coulomb|C]] SI
MC [[Coulomb|C]] SI
kC [[Coulomb|C]] SI
hC [[Coulomb|C]] SI
daC [[Coulomb|C]] SI
dC [[Coulomb|C]] SI
cC [[Coulomb|C]] SI
mC [[Coulomb|C]] SI
µC [[Coulomb|C]] SI
uC [[Coulomb|C]] SI
nC [[Coulomb|C]] SI
pC [[Coulomb|C]] SI
fC [[Coulomb|C]] SI
aC [[Coulomb|C]] SI
zC [[Coulomb|C]] SI
yC [[Coulomb|C]] SI
F [[Farad|F]] SI
YF [[Farad|F]] SI
ZF [[Farad|F]] SI
EF [[Farad|F]] SI
PF [[Farad|F]] SI
TF [[Farad|F]] SI
GF [[Farad|F]] SI
MF [[Farad|F]] SI
kF [[Farad|F]] SI
hF [[Farad|F]] SI
daF [[Farad|F]] SI
dF [[Farad|F]] SI
cF [[Farad|F]] SI
mF [[Farad|F]] SI
µF [[Farad|F]] SI
uF [[Farad|F]] SI
nF [[Farad|F]] SI
pF [[Farad|F]] SI
fF [[Farad|F]] SI
aF [[Farad|F]] SI
zF [[Farad|F]] SI
yF [[Farad|F]] SI
H [[Henry (unit)|H]] SI
YH [[Henry (unit)|H]] SI
ZH [[Henry (unit)|H]] SI
EH [[Henry (unit)|H]] SI
PH [[Henry (unit)|H]] SI
TH [[Henry (unit)|H]] SI
GH [[Henry (unit)|H]] SI
MH [[Henry (unit)|H]] SI
kH [[Henry (unit)|H]] SI
hH [[Henry (unit)|H]] SI
daH [[Henry (unit)|H]] SI
dH [[Henry (unit)|H]] SI
cH [[Henry (unit)|H]] SI
mH [[Henry (unit)|H]] SI
µH [[Henry (unit)|H]] SI
uH [[Henry (unit)|H]] SI
nH [[Henry (unit)|H]] SI
pH [[Henry (unit)|H]] SI
fH [[Henry (unit)|H]] SI
aH [[Henry (unit)|H]] SI
zH [[Henry (unit)|H]] SI
yH [[Henry (unit)|H]] SI
A [[Ampere|A]] SI
YA [[Ampere|A]] SI
ZA [[Ampere|A]] SI
EA [[Ampere|A]] SI
PA [[Ampere|A]] SI
TA [[Ampere|A]] SI
GA [[Ampere|A]] SI
MA [[Ampere|A]] SI
kA [[Ampere|A]] SI
hA [[Ampere|A]] SI
daA [[Ampere|A]] SI
dA [[Ampere|A]] SI
cA [[Ampere|A]] SI
mA [[Ampere|A]] SI
µA [[Ampere|A]] SI
uA [[Ampere|A]] SI
nA [[Ampere|A]] SI
pA [[Ampere|A]] SI
fA [[Ampere|A]] SI
aA [[Ampere|A]] SI
zA [[Ampere|A]] SI
yA [[Ampere|A]] SI
V [[Volt|V]] SI
YV [[Volt|V]] SI
ZV [[Volt|V]] SI
EV [[Volt|V]] SI
PV [[Volt|V]] SI
TV [[Volt|V]] SI
GV [[Volt|V]] SI
MV [[Volt|V]] SI
kV [[Volt|V]] SI
hV [[Volt|V]] SI
daV [[Volt|V]] SI
dV [[Volt|V]] SI
cV [[Volt|V]] SI
mV [[Volt|V]] SI
µV [[Volt|V]] SI
uV [[Volt|V]] SI
nV [[Volt|V]] SI
pV [[Volt|V]] SI
fV [[Volt|V]] SI
aV [[Volt|V]] SI
zV [[Volt|V]] SI
yV [[Volt|V]] SI
VA [[Volt-ampere|VA]] SI
YVA [[Volt-ampere|VA]] SI
ZVA [[Volt-ampere|VA]] SI
EVA [[Volt-ampere|VA]] SI
PVA [[Volt-ampere|VA]] SI
TVA [[Volt-ampere|VA]] SI
GVA [[Volt-ampere|VA]] SI
MVA [[Volt-ampere|VA]] SI
kVA [[Volt-ampere|VA]] SI
hVA [[Volt-ampere|VA]] SI
daVA [[Volt-ampere|VA]] SI
dVA [[Volt-ampere|VA]] SI
cVA [[Volt-ampere|VA]] SI
mVA [[Volt-ampere|VA]] SI
µVA [[Volt-ampere|VA]] SI
uVA [[Volt-ampere|VA]] SI
nVA [[Volt-ampere|VA]] SI
pVA [[Volt-ampere|VA]] SI
fVA [[Volt-ampere|VA]] SI
aVA [[Volt-ampere|VA]] SI
zVA [[Volt-ampere|VA]] SI
yVA [[Volt-ampere|VA]] SI
Ω [[Ohm|Ω]] SI
YΩ.m [[Electrical resistivity and conductivity#Definition|YΩ⋅m]] 1e24
ZΩ.m [[Electrical resistivity and conductivity#Definition|ZΩ⋅m]] 1e21
EΩ.m [[Electrical resistivity and conductivity#Definition|EΩ⋅m]] 1e18
PΩ.m [[Electrical resistivity and conductivity#Definition|PΩ⋅m]] 1e15
TΩ.m [[Electrical resistivity and conductivity#Definition|TΩ⋅m]] 1e12
GΩ.m [[Electrical resistivity and conductivity#Definition|GΩ⋅m]] 1e9
MΩ.m [[Electrical resistivity and conductivity#Definition|MΩ⋅m]] 1e6
kΩ.m [[Electrical resistivity and conductivity#Definition|kΩ⋅m]] 1e3
Ω.m [[Electrical resistivity and conductivity#Definition|Ω⋅m]] 1
mΩ.m [[Electrical resistivity and conductivity#Definition|mΩ⋅m]] 1e-3
µΩ.m [[Electrical resistivity and conductivity#Definition|µΩ⋅m]] 1e-6
uΩ.m [[Electrical resistivity and conductivity#Definition|µΩ⋅m]] 1e-6
nΩ.m [[Electrical resistivity and conductivity#Definition|nΩ⋅m]] 1e-9
pΩ.m [[Electrical resistivity and conductivity#Definition|pΩ⋅m]] 1e-12
fΩ.m [[Electrical resistivity and conductivity#Definition|fΩ⋅m]] 1e-15
aΩ.m [[Electrical resistivity and conductivity#Definition|aΩ⋅m]] 1e-18
zΩ.m [[Electrical resistivity and conductivity#Definition|zΩ⋅m]] 1e-21
yΩ.m [[Electrical resistivity and conductivity#Definition|yΩ⋅m]] 1e-24
R [[Rayleigh (unit)|R]] SI
G [[Gauss (unit)|G]] SI
aG [[Attogauss|G]] SI
cG [[Centigauss|G]] SI
daG [[Decagauss|G]] SI
dG [[Decigauss|G]] SI
EG [[Exagauss|G]] SI
fG [[Femtogauss|G]] SI
GG [[Gigagauss|G]] SI
hG [[Hectogauss|G]] SI
kG [[Kilogauss|G]] SI
MG [[Megagauss|G]] SI
mG [[Milligauss|G]] SI
uG [[Microgauss|G]] SI
µG [[Microgauss|G]] SI
nG [[Nanogauss|G]] SI
PG [[Petagauss|G]] SI
pG [[Picogauss|G]] SI
TG [[Teragauss|G]] SI
yG [[Yoctogauss|G]] SI
YG [[Yottagauss|G]] SI
zG [[Zeptogauss|G]] SI
ZG [[Zettagauss|G]] SI
T [[Tesla (unit)|T]] SI
aT [[Attotesla|T]] SI
cT [[Centitesla|T]] SI
daT [[Decatesla|T]] SI
dT [[Decitesla|T]] SI
ET [[Exatesla|T]] SI
fT [[Femtotesla|T]] SI
GT [[Gigatesla|T]] SI
hT [[Hectotesla|T]] SI
kT [[Kilotesla|T]] SI
MT [[Megatesla|T]] SI
mT [[Millitesla|T]] SI
uT [[Microtesla|T]] SI
µT [[Microtesla|T]] SI
nT [[Nanotesla|T]] SI
PT [[Petatesla|T]] SI
pT [[Picotesla|T]] SI
TT [[Teratesla|T]] SI
yT [[Yoctotesla|T]] SI
YT [[Yottatesla|T]] SI
zT [[Zeptotesla|T]] SI
ZT [[Zettatesla|T]] SI
== Astrophysics ==
au [[Astronomical unit|au]]
c [[Speed of light|''c'']]
ly [[Light-year|ly]]
dex [[decimal exponent|dex]]
Earth mass [[Earth mass|''M''<sub>🜨</sub>]]
Earth radius [[Earth radius|''R''<sub>🜨</sub>]]
M_Earth [[Earth mass|''M''<sub>🜨</sub>]]
R_Earth [[Earth radius|''R''<sub>🜨</sub>]]
M+ [[Earth mass|''M''<sub>🜨</sub>]]
R+ [[Earth radius|''R''<sub>🜨</sub>]]
Jupiter mass [[Jupiter mass|''M''<sub>J</sub>]]
Jupiter radius [[Jupiter radius|''R''<sub>J</sub>]]
M_Jupiter [[Jupiter mass|''M''<sub>J</sub>]]
R_Jupiter [[Jupiter radius|''R''<sub>J</sub>]]
Solar mass [[Solar mass|''M''<sub>☉</sub>]]
solar mass [[Solar mass|''M''<sub>☉</sub>]]
M_Solar [[Solar mass|''M''<sub>☉</sub>]]
M_solar [[Solar mass|''M''<sub>☉</sub>]]
R_Solar [[Solar radius|''R''<sub>☉</sub>]]
R_solar [[Solar radius|''R''<sub>☉</sub>]]
Solar radius [[Solar radius|''R''<sub>☉</sub>]]
solar radius [[Solar radius|''R''<sub>☉</sub>]]
Solar luminosity [[Solar luminosity|''L''<sub>☉</sub>]]
solar luminosity [[Solar luminosity|''L''<sub>☉</sub>]]
L_solar [[Solar luminosity|''L''<sub>☉</sub>]]
L_Solar [[Solar luminosity|''L''<sub>☉</sub>]]
Lo [[Solar luminosity|''L''<sub>☉</sub>]]
pc2 [[Parsec|pc<sup>2</sup>]]
pc3 [[Parsec|pc<sup>3</sup>]]
kpc2 [[Parsec#Parsecs and kiloparsecs|kpc<sup>2</sup>]]
kpc3 [[Parsec#Parsecs and kiloparsecs|kpc<sup>3</sup>]]
kpc [[Parsec#Parsecs and kiloparsecs|kpc]]
Mpc2 [[Parsec#Megaparsecs and gigaparsecs|Mpc<sup>2</sup>]]
Mpc3 [[Parsec#Megaparsecs and gigaparsecs|Mpc<sup>3</sup>]]
Mpc [[Parsec#Megaparsecs and gigaparsecs|Mpc]]
Gpc2 [[Parsec#Megaparsecs and gigaparsecs|Gpc<sup>2</sup>]]
Gpc3 [[Parsec#Megaparsecs and gigaparsecs|Gpc<sup>3</sup>]]
Gpc [[Parsec#Megaparsecs and gigaparsecs|Gpc]]
== Nuclear physics and chemistry ==
cm-1 [[Wavenumber|cm<sup>−1</sup>]]
u [[Unified atomic mass unit|u]]
osmol [[Osmole (unit)|osmol]]
Osm [[Osmole (unit)|Osm]]
M [[Molarity|M]]
TM [[Molarity|M]] SI
GM [[Molarity|M]] SI
MM [[Molarity|M]] SI
kM [[Molarity|M]] SI
hM [[Molarity|M]] SI
daM [[Molarity|M]] SI
dM [[Molarity|M]] SI
cM [[Molarity|M]] SI
mM [[Molarity|M]] SI
uM [[Molarity|M]] 1e-6
nM [[Molarity|M]] SI
pM [[Molarity|M]] SI
kg.mol-1 [[Molar mass|kg⋅mol<sup>−1</sup>]]
kg/mol [[Molar mass|kg/mol]]
g.mol-1 [[Molar mass|g⋅mol<sup>−1</sup>]]
g/mol [[Molar mass|g/mol]]
eV/c2 [[Electronvolt#Mass|eV/''c''<sup>2</sup>]]
keV/c2 [[Electronvolt#Mass|keV/''c''<sup>2</sup>]]
MeV/c2 [[Electronvolt#Mass|MeV/''c''<sup>2</sup>]]
GeV/c2 [[Electronvolt#Mass|GeV/''c''<sup>2</sup>]]
TeV/c2 [[Electronvolt#Mass|TeV/''c''<sup>2</sup>]]
eV [[Electronvolt|eV]]
meV [[Electronvolt|meV]]
keV [[Electronvolt|keV]]
MeV [[Electronvolt|MeV]]
GeV [[Electronvolt|GeV]]
TeV [[Electronvolt|TeV]]
mol-1 [[Avogadro constant|mol<sup>−1</sup>]]
J.mol-1 [[Joule per mole|J⋅mol<sup>−1</sup>]]
J/mol [[Joule per mole|J/mol]]
kJ.mol-1 [[Joule per mole|kJ⋅mol<sup>−1</sup>]]
kJ/mol [[Joule per mole|kJ/mol]]
MJ.mol-1 [[Joule per mole|MJ⋅mol<sup>−1</sup>]]
MJ/mol [[Joule per mole|MJ/mol]]
GJ.mol-1 [[Joule per mole|GJ⋅mol<sup>−1</sup>]]
GJ/mol [[Joule per mole|GJ/mol]]
TJ.mol-1 [[Joule per mole|TJ⋅mol<sup>−1</sup>]]
TJ/mol [[Joule per mole|TJ/mol]]
== Numbers and phrases ==
pp [[Page (paper)|pp]]
ppb [[Parts per billion|ppb]] 1e-9
ppm [[Parts per million|ppm]] 1e-6
billiard [[Orders of magnitude (numbers)#1015|billiard]] 1e15
billion [[1,000,000,000|billion]] 1e9
billionth [[1,000,000,000|billionth]] 1e-9
billionths [[1,000,000,000|billionths]] 1e-9
decilliard [[Orders of magnitude (numbers)#1063|decilliard]] 1e63
decillion [[Orders of magnitude (numbers)#1033|decillion]] 1e33
decillionth [[Orders of magnitude (numbers)#1033|decillionth]] 1e-33
decillionths [[Orders of magnitude (numbers)#1033|decillionths]] 1e-33
milliard [[1,000,000,000|milliard]] 1e9
million [[Million|million]] 1e6
millionth [[Million|millionth]] 1e-6
millionths [[Million|millionths]] 1e-6
nonilliard [[Orders of magnitude (numbers)#1057|nonilliard]] 1e57
nonillion [[Orders of magnitude (numbers)#1030|nonillion]] 1e30
nonillionth [[Orders of magnitude (numbers)#1030|nonillionth]] 1e-30
nonillionths [[Orders of magnitude (numbers)#1030|nonillionths]] 1e-30
octilliard [[Orders of magnitude (numbers)#1051|octilliard]] 1e51
octillion [[Orders of magnitude (numbers)#1027|octillion]] 1e27
octillionth [[Orders of magnitude (numbers)#1027|octillionth]] 1e-27
octillionths [[Orders of magnitude (numbers)#1027|octillionths]] 1e-27
quadrilliard [[Orders of magnitude (numbers)#1027|quadrilliard]] 1e27
quadrillion [[Orders of magnitude (numbers)#1015|quadrillion]] 1e15
quadrillionth [[Orders of magnitude (numbers)#1015|quadrillionth]] 1e-15
quadrillionths [[Orders of magnitude (numbers)#1015|quadrillionths]] 1e-15
quintilliard [[Orders of magnitude (numbers)#1033|quintilliard]] 1e33
quintillion [[Orders of magnitude (numbers)#1018|quintillion]] 1e18
quintillionth [[Orders of magnitude (numbers)#1018|quintillionth]] 1e-18
quintillionths [[Orders of magnitude (numbers)#1018|quintillionths]] 1e-18
septilliard [[Orders of magnitude (numbers)#1045|septilliard]] 1e45
septillion [[Orders of magnitude (numbers)#1024|septillion]] 1e24
septillionth [[Orders of magnitude (numbers)#1024|septillionth]] 1e-24
septillionths [[Orders of magnitude (numbers)#1024|septillionths]] 1e-24
sextilliard [[Orders of magnitude (numbers)#1039|sextilliard]] 1e39
sextillion [[Orders of magnitude (numbers)#1021|sextillion]] 1e21
sextillionth [[Orders of magnitude (numbers)#1021|sextillionth]] 1e-21
sextillionths [[Orders of magnitude (numbers)#1021|sextillionths]] 1e-21
trilliard [[Orders of magnitude (numbers)#1021|trilliard]] 1e21
trillion [[Orders of magnitude (numbers)#1012|trillion]] 1e12
trillionth [[Orders of magnitude (numbers)#1012|trillionth]] 1e-12
trillionths [[Orders of magnitude (numbers)#1012|trillionths]] 1e-12
== Angles ==
% % Percent ANGLE 0.01
percent % Percent ANGLE 0.01
per cent % Percent ANGLE 0.01
‰ ‰ Per mil ANGLE 1e-3
per mil ‰ Per mil ANGLE 1e-3
per mill ‰ Per mil ANGLE 1e-3
per mille ‰ Per mil ANGLE 1e-3
permil ‰ Per mil ANGLE 1e-3
permill ‰ Per mil ANGLE 1e-3
permille ‰ Per mil ANGLE 1e-3
° ° Degree (angle) ANGLE pi/180
deg ° Degree (angle) ANGLE pi/180
' ′ Minute of arc ANGLE pi/10800
′ ′ Minute of arc ANGLE pi/10800
arcmin ′ Minute of arc ANGLE pi/10800
arcminute ′ Minute of arc ANGLE pi/10800
" ″ Second of arc ANGLE pi/648000
″ ″ Second of arc ANGLE pi/648000
arcsec ″ Second of arc ANGLE pi/648000
arcsecond ″ Second of arc ANGLE pi/648000
mas [[Milliarcsecond|mas]] pi/648000000
]=]
-- If val has "|long scale=on" the following definitions are used
-- (then, if not found here, the normal definitions are used).
-- Unit code [[Link|Symbol]] Flags/Scale
local builtin_units_long_scale = [=[
== Long scale numbers and phrases ==
billion [[Orders of magnitude (numbers)#1012|billion]] 1e12
billionth [[Orders of magnitude (numbers)#1012|billionth]] 1e-12
billionths [[Orders of magnitude (numbers)#1012|billionths]] 1e-12
decillion [[Orders of magnitude (numbers)#1060|decillion]] 1e60
decillionth [[Orders of magnitude (numbers)#1060|decillionth]] 1e-60
decillionths [[Orders of magnitude (numbers)#1060|decillionths]] 1e-60
nonillion [[Orders of magnitude (numbers)#1054|nonillion]] 1e54
nonillionth [[Orders of magnitude (numbers)#1054|nonillionth]] 1e-54
nonillionths [[Orders of magnitude (numbers)#1054|nonillionths]] 1e-54
octillion [[Orders of magnitude (numbers)#1048|octillion]] 1e48
octillionth [[Orders of magnitude (numbers)#1048|octillionth]] 1e-48
octillionths [[Orders of magnitude (numbers)#1048|octillionths]] 1e-48
quadrillion [[Orders of magnitude (numbers)#1024|quadrillion]] 1e24
quadrillionth [[Orders of magnitude (numbers)#1024|quadrillionth]] 1e-24
quadrillionths [[Orders of magnitude (numbers)#1024|quadrillionths]] 1e-24
quintillion [[Orders of magnitude (numbers)#1030|quintillion]] 1e30
quintillionth [[Orders of magnitude (numbers)#1030|quintillionth]] 1e-30
quintillionths [[Orders of magnitude (numbers)#1030|quintillionths]] 1e-30
septillion [[Orders of magnitude (numbers)#1042|septillion]] 1e42
septillionth [[Orders of magnitude (numbers)#1042|septillionth]] 1e-42
septillionths [[Orders of magnitude (numbers)#1042|septillionths]] 1e-42
sextillion [[Orders of magnitude (numbers)#1036|sextillion]] 1e36
sextillionth [[Orders of magnitude (numbers)#1036|sextillionth]] 1e-36
sextillionths [[Orders of magnitude (numbers)#1036|sextillionths]] 1e-36
trillion [[Orders of magnitude (numbers)#1018|trillion]] 1e18
trillionth [[Orders of magnitude (numbers)#1018|trillionth]] 1e-18
trillionths [[Orders of magnitude (numbers)#1018|trillionths]] 1e-18
]=]
return { builtin_units = builtin_units, builtin_units_long_scale = builtin_units_long_scale }
81ae3510367fd477db8e031a5103f8a573b86138
Sirius
0
33
72
2022-09-04T11:44:31Z
SpaceMan
2
Created page with "Sirius is the brightest star system in Earth's night sky. The name "Sirius" is derived from the Ancient Greek "Seirios", which means "glowing" or "scorcher". What appears to be a single star to the naked eye is actually a binary system of a white star with a faint [[White dwarf]]. This system is formally known as Alpha Canis Majoris or alpha CMa. **Brightness** Sirius is the brightest star system in the night sky with almost twice the brightness of the second brightest..."
wikitext
text/x-wiki
Sirius is the brightest star system in Earth's night sky. The name "Sirius" is derived from the Ancient Greek "Seirios", which means "glowing" or "scorcher". What appears to be a single star to the naked eye is actually a binary system of a white star with a faint [[White dwarf]]. This system is formally known as Alpha Canis Majoris or alpha CMa.
**Brightness**
Sirius is the brightest star system in the night sky with almost twice the brightness of the second brightest star, [[Canopus]]. However, it is not as bright as the moon, Venus or Jupiter. In fact, even [[Mars]] and [[Mercury]] appear brighter than Sirius at times.
**Types of Sirius**
The two stars of the Sirius system are termed as Sirius A and Sirius B. Sirius A is a white
main-sequence star with an estimated surface temperature of 9,940 K. It has an estimated mass which is twice that of the Sun. Sirius B is a star that has already evolved off the main sequence and transformed into a white dwarf. It has a mass almost equal to that of the Sun. It is one of the most massive white dwarfs known to us.
**Colour**
Greek astronomer Ptolemy had described the star of Sirius to be red in colour around 150 CE. However, poet Marcus Manilius described it as blue in his poems around 1 CE and ancient China has been describing it as white since 4 CE. Astronomers believe that this [[Star]] keeps changing its colour. However, the reason is still being debated upon.
bb380f560c64f197557d78e8b843b66ad0afe04f
73
72
2022-09-04T11:46:34Z
SpaceMan
2
Protected "[[Sirius]]" ([Edit=Allow only logged in users] (indefinite))
wikitext
text/x-wiki
Sirius is the brightest star system in Earth's night sky. The name "Sirius" is derived from the Ancient Greek "Seirios", which means "glowing" or "scorcher". What appears to be a single star to the naked eye is actually a binary system of a white star with a faint [[White dwarf]]. This system is formally known as Alpha Canis Majoris or alpha CMa.
**Brightness**
Sirius is the brightest star system in the night sky with almost twice the brightness of the second brightest star, [[Canopus]]. However, it is not as bright as the moon, Venus or Jupiter. In fact, even [[Mars]] and [[Mercury]] appear brighter than Sirius at times.
**Types of Sirius**
The two stars of the Sirius system are termed as Sirius A and Sirius B. Sirius A is a white
main-sequence star with an estimated surface temperature of 9,940 K. It has an estimated mass which is twice that of the Sun. Sirius B is a star that has already evolved off the main sequence and transformed into a white dwarf. It has a mass almost equal to that of the Sun. It is one of the most massive white dwarfs known to us.
**Colour**
Greek astronomer Ptolemy had described the star of Sirius to be red in colour around 150 CE. However, poet Marcus Manilius described it as blue in his poems around 1 CE and ancient China has been describing it as white since 4 CE. Astronomers believe that this [[Star]] keeps changing its colour. However, the reason is still being debated upon.
bb380f560c64f197557d78e8b843b66ad0afe04f
75
73
2022-09-04T11:48:43Z
SpaceMan
2
Sirius
wikitext
text/x-wiki
[[File:Siriusstar.jpg|thumb|Sirius star]]
Sirius is the brightest star system in Earth's night sky. The name "Sirius" is derived from the Ancient Greek "Seirios", which means "glowing" or "scorcher". What appears to be a single star to the naked eye is actually a binary system of a white star with a faint [[White dwarf]]. This system is formally known as Alpha Canis Majoris or alpha CMa.
**Brightness**
Sirius is the brightest star system in the night sky with almost twice the brightness of the second brightest star, [[Canopus]]. However, it is not as bright as the moon, Venus or Jupiter. In fact, even [[Mars]] and [[Mercury]] appear brighter than Sirius at times.
**Types of Sirius**
The two stars of the Sirius system are termed as Sirius A and Sirius B. Sirius A is a white
main-sequence star with an estimated surface temperature of 9,940 K. It has an estimated mass which is twice that of the Sun. Sirius B is a star that has already evolved off the main sequence and transformed into a white dwarf. It has a mass almost equal to that of the Sun. It is one of the most massive white dwarfs known to us.
**Colour**
Greek astronomer Ptolemy had described the star of Sirius to be red in colour around 150 CE. However, poet Marcus Manilius described it as blue in his poems around 1 CE and ancient China has been describing it as white since 4 CE. Astronomers believe that this [[Star]] keeps changing its colour. However, the reason is still being debated upon.
a89cb8b357886c650cd272c113268f4028ec6e91
File:Siriusstar.jpg
6
34
74
2022-09-04T11:48:12Z
SpaceMan
2
Uploaded own work with UploadWizard
wikitext
text/x-wiki
=={{int:filedesc}}==
{{Information
|description={{en|1=Sirius star}}
|date=2022-09-04
|source={{own}}
|author=[[User:SpaceMan|SpaceMan]]
|permission=
|other versions=
}}
=={{int:license-header}}==
{{self|cc-by-sa-4.0}}
[[Category:Star]]
f0e4db20c0a645529105d4417b0ebec5c2f1b47f
Astronomy Database portal
0
30
76
71
2022-09-04T11:50:00Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from [https://cds.u-strasbg.fr/ CDS] .
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
[https://astrobase.miraheze.org/wiki/Sirius Sirius]
41ff058823eed3a28416991dc9b269985d5335b4
77
76
2022-09-04T11:50:15Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from [https://cds.u-strasbg.fr/ CDS] .
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]<br>
[https://astrobase.miraheze.org/wiki/Sirius Sirius]
422fd453b6f248957848919d0441bd6bb4fb86ac
83
77
2022-09-04T14:18:48Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from [https://cds.u-strasbg.fr/ CDS] .
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]<br>
[https://astrobase.miraheze.org/wiki/Sirius Sirius]<br>
[https://astrobase.miraheze.org/wiki/Canopus Canopus]
38eeaf4fa86e377ccaa4b0dfd3e621eac19c17b9
84
83
2022-09-04T14:19:27Z
SpaceMan
2
/* Astronomy Database Portal */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from verious sources.
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]<br>
[https://astrobase.miraheze.org/wiki/Sirius Sirius]<br>
[https://astrobase.miraheze.org/wiki/Canopus Canopus]
4c9f1e007ee9ad212661e57418f5bcf1f8d08d1c
85
84
2022-09-04T14:19:48Z
SpaceMan
2
Protected "[[Astronomy Database portal]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from verious sources.
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]<br>
[https://astrobase.miraheze.org/wiki/Sirius Sirius]<br>
[https://astrobase.miraheze.org/wiki/Canopus Canopus]
4c9f1e007ee9ad212661e57418f5bcf1f8d08d1c
87
85
2022-09-04T15:15:02Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from verious sources.
==Star==
[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]<br>
[https://astrobase.miraheze.org/wiki/Sirius Sirius]<br>
[https://astrobase.miraheze.org/wiki/Canopus Canopus]
{| class="wikitable"
|+STAR
|-
|[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
|-
|[https://astrobase.miraheze.org/wiki/Sirius Sirius]
|-
|[https://astrobase.miraheze.org/wiki/Canopus Canopus]
|}
b89508a4c96d3a61012907cb56c1bda86a0f98e4
88
87
2022-09-04T15:15:29Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
==Astronomy Database Portal==
This is Astronomy Database Portal (ADP).
Note: following content is taken from verious sources.
==Star==
{| class="wikitable"
|+STAR
|-
|[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
|-
|[https://astrobase.miraheze.org/wiki/Sirius Sirius]
|-
|[https://astrobase.miraheze.org/wiki/Canopus Canopus]
|}
83bd14d43ff8a54873d17d37f7d870b73576e56e
Main Page
0
1
78
66
2022-09-04T11:50:52Z
SpaceMan
2
/* Welcome to {{SITENAME}}! */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently a development.
===Quick List===
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
===Astronomy Database Portal===
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
837402f9e3935893c3edda0f84dbd74e9ea20317
86
78
2022-09-04T15:06:43Z
SpaceMan
2
/* Welcome to {{SITENAME}}! */
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
== Welcome to {{SITENAME}}! ==
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently in development.
===Quick List===
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
===Astronomy Database Portal===
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
98c1a3cbd13a23527d385108656c16a36289f82c
Category:Pages with reference errors
14
36
82
2022-09-04T14:15:19Z
SpaceMan
2
Created page with "Star"
wikitext
text/x-wiki
Star
85a7de6e270547e88998d71994b1464d01295177
Canopus
0
37
90
89
2022-09-04T15:24:25Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{short description|Bright giant star in the constellation of Carina}}
{{Other uses}}
{{Starbox begin
| name=Canopus
}}
{{Starbox image
| image=[[File:Canopus.jpg|255px]]
| caption=An image of Canopus by [[Expedition 6]]
}}
{{Starbox observe
| epoch=J2000
| constell=[[Carina (constellation)|Carina]]
| pronounce={{IPAc-en|k|ə|ˈ|n|oʊ|p|ə|s}}<ref>{{OED|Canopus}}</ref>
| ra={{RA|06|23|57.10988}}<ref name="van Leeuwen2007">{{cite journal | title=Validation of the new Hipparcos reduction | last1=van Leeuwen | first1=F. | journal=Astronomy and Astrophysics | volume=474 | issue=2 | pages=653–664 | date=2007 | arxiv=0708.1752 | bibcode=2007A&A...474..653V | doi=10.1051/0004-6361:20078357 | s2cid=18759600 }} [http://webviz.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b48255b3&-out.add=.&-source=I/311/hip2&recno=30362 Vizier catalog entry ]</ref>
| dec={{DEC|-52|41|44.3810}}<ref name="van Leeuwen2007"/>
| appmag_v=−0.74<ref name="Ducati 2002">{{cite journal | title=Catalogue of Stellar Photometry in Johnson's 11-color system | last1=Ducati | first1=J. R. | journal=CDS/ADC Collection of Electronic Catalogues | volume=2237 | pages=0 | date=2002 | bibcode=2002yCat.2237....0D }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b360304a&-out.add=.&-source=II/237/colors&recno=1155 Vizier catalog entry ]</ref>
}}
{{Starbox character
| type=
| class=A9 II<ref name=perkins>{{cite journal|bibcode=1989ApJS...69..301G|title=The early F-type stars – Refined classification, confrontation with Stromgren photometry, and the effects of rotation|journal=Astrophysical Journal Supplement Series|volume=69|pages=301|last1=Gray|first1=R. O.|last2=Garrison|first2=R. F.|year=1989|doi=10.1086/191315}}</ref><ref>{{cite journal|bibcode=1993ASPC...45...59L|title=A Spectroscopic Study of High Galactic Latitude F Supergiant Stars|journal=Luminous High-Latitude Stars. The International Workshop on Luminous High-Latitude Stars|volume=45|pages=59|last1=Lopez-Cruz|first1=O.|last2=Garrison|first2=R. F.|year=1993}}</ref>
| b-v=+0.15<ref name="Ducati 2002"/>
| u-b=+0.10<ref name="Ducati 2002"/>
| variable=
}}
{{Starbox astrometry
| radial_v={{val|20.3|0.5}}<ref name="Gontcharov 2007">{{cite journal | title=Pullkovo Compilation of Radial Velocities for 39495 Hipparcos stars in a common system | last1=Gontcharov | first1=G. A. | journal=Astronomy Letters | volume=32 | issue=1 | pages=759–771 | date=2007 | bibcode=2006AstL...32..759G | doi=10.1134/S1063773706110065|arxiv = 1606.08053 | s2cid=119231169 }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b5f60fbd&-out.add=.&-source=III/252/table8&recno=9232 Vizier catalog entry ]</ref>
| prop_mo_ra=19.93<ref name="van Leeuwen2007"/>
| prop_mo_dec=23.24<ref name="van Leeuwen2007"/>
| parallax=10.55
| p_error=0.56
| parallax_footnote=<ref name="van Leeuwen2007"/>
| absmag_v=–5.71<ref name=smiljanic2006/>
|arxiv = 1606.08053 }}
{{Starbox detail
| metal_fe=–0.07<ref name=smiljanic2006/>
| mass={{Val|8.0|0.3}}<ref name=vlti>{{cite journal|bibcode=2013MNRAS.434..437C|arxiv=1306.3288|title=Fundamental parameters of 16 late-type stars derived from their angular diameter measured with VLTI/AMBER|journal=Monthly Notices of the Royal Astronomical Society|volume=434|issue=1|pages=437–450|last1=Cruzalèbes|first1=P.|last2=Jorissen|first2=A.|last3=Rabbia|first3=Y.|last4=Sacuto|first4=S.|last5=Chiavassa|first5=A.|last6=Pasquato|first6=E.|last7=Plez|first7=B.|last8=Eriksson|first8=K.|last9=Spang|first9=A.|last10=Chesneau|first10=O.|year=2013|doi=10.1093/mnras/stt1037|s2cid=49573767}}</ref> (2013)<br/>{{val|10.1|0.1}}<ref name=Tetzlaff2011/> (2011)
| radius={{Val|71|4}}<ref name=vlti/> (2013)<br>{{val|73.3|5.2}}<ref name=DomicianoDeSouza>{{cite journal|doi=10.1051/0004-6361/202140478|title=Refined fundamental parameters of Canopus from combined near-IR interferometry and spectral energy distribution|year=2021|last1=Domiciano De Souza|first1=A.|last2=Zorec|first2=J.|last3=Millour|first3=F.|last4=Le Bouquin|first4=J.-B.|last5=Spang|first5=A.|last6=Vakili|first6=F.|journal=Astronomy & Astrophysics|volume=654|pages=A19|arxiv=2109.07153|bibcode=2021A&A...654A..19D|s2cid=237513623}}</ref> (2021)
| gravity={{Val|1.70|0.05}}<ref name=DomicianoDeSouza/>
| rotational_velocity=9<ref name=ayres2018/>
| rotation={{val|298|u=days|p=≥}}<ref name=Testa2004/>
| luminosity=10,700<ref name=vlti/>
| temperature=7,400<ref name=ayres2018>{{cite journal |bibcode=2018ApJ...854...95A |title=Cracking the Conundrum of F-supergiant Coronae |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |year=2018 |volume=854 |issue=2 |page=95 |doi=10.3847/1538-4357/aaa6d7 |arxiv=1802.02552 |s2cid=119101035 }}</ref>
| age_myr = {{val|25.1|2.5}}<ref name=Tetzlaff2011>{{cite journal | title=A catalogue of young runaway Hipparcos stars within 3 kpc from the Sun | last1=Tetzlaff | first1=N. | last2=Neuhäuser | first2=R. | last3=Hohle | first3=M. M. | journal=Monthly Notices of the Royal Astronomical Society | volume=410 | issue=1 | pages=190–200 | date=January 2011 | doi=10.1111/j.1365-2966.2010.17434.x | arxiv=1007.4883 | bibcode=2011MNRAS.410..190T | s2cid=118629873 }}</ref>
}}
{{Starbox catalog
| names={{odlist | name=Suhayl | name2=Suhel | name3=Suhail | B=α Carinae | CPD=−52°1941 | FK5=245 | HD=45348 | HIP=30438 | HR=2326 | SAO=234480| GC=8302 }}<ref name=SIMBAD>{{cite simbad | title=alf Car | access-date=2019-03-09 }}</ref>
}}
{{Starbox reference
| Simbad=canopus
}}
{{Starbox end}}
'''Canopus''' is the brightest star in the southern [[constellation]] of [[Carina (constellation)|Carina]] and the [[list of brightest stars|second-brightest star]] in the [[night sky]]. It is also [[Bayer designation|designated]] '''α Carinae''', which is [[Latinisation of names|Latinised]] to '''Alpha Carinae'''. With a [[visual apparent magnitude]] of −0.74, it is outshone only by [[Sirius]]. Located around {{val|310|ul=light-years}} from the [[Sun]], Canopus is a [[bright giant]] of [[spectral type A9]], so it is essentially white when seen with the naked eye. It has a luminosity over 10,000 times the [[luminosity of the Sun]], is eight times as [[mass of the Sun|massive]], and has expanded to 71 times the [[Sun's radius]]. Its enlarged [[photosphere]] has an [[effective temperature]] of around {{val|7,400|fmt=commas|u=K}}. Canopus is undergoing [[stellar core|core]] [[helium fusion|helium burning]] and is currently in the so-called [[blue loop]] phase of its [[stellar evolution|evolution]], having already passed through the [[red-giant branch]] after exhausting the hydrogen in its core. Canopus is a [[X-ray astronomy|source of X-rays]], which are likely being emitted from its [[stellar corona|corona]].
The prominent appearance of Canopus means it has been the subject of mythological lore among many ancient peoples. Its proper name is generally considered to originate from the [[Greek mythology|mythological]] [[Canopus (mythology)|Canopus]], who was a navigator for [[Menelaus]], king of [[Sparta]]. The [[acronychal rising]] marked the date of the Ptolemaia festival in Egypt. In ancient India, it was named [[Agastya]] after the revered [[Vedas|Vedic]] sage. For Chinese astronomers, it was known as the [[Old Man of the South Pole]].
==Nomenclature==
The name ''Canopus'' is a Latinisation of the [[Ancient Greek]] name Κάνωβος/Kanôbos, recorded in Claudius Ptolemy's ''[[Almagest]]'' (c.150 AD). Eratosthenes used the same spelling.<ref name="ridpathCr"/> Hipparchos wrote it as Κάνωπος. [[John Flamsteed]] wrote Canobus,<ref>{{cite book|last=Flamsteed|first=John|title=Atlas coelestis|location=London, United Kingdom|date=1729|pages=Constellation Map of Southern Hemisphere|url=http://lhldigital.lindahall.org/u?/astro_atlas,1191}}</ref> as did [[Edmond Halley]] in his 1679 ''Catalogus Stellarum Australium''.<ref name="Halley 1679">{{cite book|last=Halley|first=Edmond|title=Catalogus stellarum australium; sive, Supplementum catalogi Tychenici, exhibens longitudines et latitudines stellarum fixarum, quae, prope polum Antarcticum sitae, in horizonte Uraniburgico Tychoni inconspicuae fuere, accurato calculo ex distantiis supputatas, & ad annum 1677 completum correctas...Accedit appendicula de rebus quibusdam astronomicis|publisher=T. James|location=London|date=1679|pages=30|url=http://babel.hathitrust.org/cgi/pt?id=mdp.39015007000170;view=1up;seq=41;size=150}}</ref> The name has two possible derivations, both listed in [[Richard Hinckley Allen]]'s seminal ''[[Star Names: Their Lore and Meaning]]''.
* [[Argo Navis]] was the ship used by [[Jason]] and the Argonauts in the legend of the [[Trojan War]]. The brightest star in the constellation was given the name of a ship's pilot from another Greek legend: [[Canopus (mythology)|Canopus]], pilot of [[Menelaus]]' ship on his quest to retrieve [[Helen of Troy]] after she was taken by [[Paris (mythology)|Paris]].<ref name="hinkley63">{{cite book|first=Richard Hinckley|last=Allen|author-link=Richard Hinckley Allen|date=1963|orig-year=1899|title=Star Names: Their Lore and Meaning|pages=[https://archive.org/details/starnamestheirlo00alle/page/67 67–72]|edition=Revised|publisher=Dover Publications|location=New York|isbn=0-486-21079-0|url-access=registration|url=https://archive.org/details/starnamestheirlo00alle/page/67}}</ref>
* A ruined ancient Egyptian port named [[Canopus, Egypt|Canopus]] lies near the mouth of the [[Nile]], site of the [[Battle of the Nile]]. It is speculated that its name is derived from the Egyptian [[Coptic language|Coptic]] ''Kahi Nub'' ("Golden Earth"), which refers to how Canopus would have appeared near the horizon in [[ancient Egypt]], reddened by atmospheric extinction from that position.<ref name="hinkley63"/><ref name=lynn1905>{{cite journal |bibcode=1905Obs....28..289L |title=The brightest fixed star and its name |last1=Lynn |first1=W. T. |journal=The Observatory |year=1905 |volume=28 |page=289 }}</ref>
In 2016, the [[International Astronomical Union]] organized a [[IAU Working Group on Star Names|Working Group on Star Names]] (WGSN) to catalog and standardize proper names for stars.<ref name="WGSN">{{cite web | url=https://www.iau.org/science/scientific_bodies/working_groups/280/ | title=IAU Working Group on Star Names (WGSN) | website=iau.org | publisher=[[International Astronomical Union]] | access-date=22 May 2016}}</ref> The WGSN's first bulletin of July 2016 included a table of the first two batches of names approved by the WGSN, which included ''Canopus'' for this star.<ref name="WGSN1">{{cite web | url=https://www.iau.org/static/science/scientific_bodies/working_groups/280/WGSN_bulletin1.pdf | title=Bulletin of the IAU Working Group on Star Names, No. 1 | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06 }}</ref> Canopus is now included in the ''IAU Catalog of Star Names''.<ref name="IAU-CSN">{{cite web | url=https://www.iau.org/public/themes/naming_stars/ | title=IAU Catalog of Star Names | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06}}</ref>
Canopus traditionally marked the rudder of the ship [[Argo Navis]].<ref>{{cite journal | title = On Frederick de Houtman's Catalogue of Southern Stars, and the Origin of the Southern Constellations | last1= Knobel|first1=E. B. |journal = [[Monthly Notices of the Royal Astronomical Society]] | volume= 77| issue= 5 | pages=414–432 [422] | bibcode = 1917MNRAS..77..414K |date=1917 | doi=10.1093/mnras/77.5.414| doi-access=free }}</ref> German celestial cartographer [[Johann Bayer]] gave it—as the brightest star in the constellation—the [[Bayer designation|designation]] of ''α Argus'' ([[Latinisation of names|Latinised]] to ''Alpha Argus'') in 1603. In 1763, French astronomer [[Nicolas Louis de Lacaille]] divided the huge constellation into three smaller ones,<ref name=Glass2012>{{cite book | title=Nicolas-Louis De La Caille, Astronomer and Geodesist | first=Ian Stewart | last=Glass | date=November 17, 2012 | page=73 | isbn=9780191649608 | publisher=OUP Oxford | url=https://www.google.com/books/edition/Nicolas_Louis_De_La_Caille_Astronomer_an/eZjlHAIBeRAC?hl=en&gbpv=1&pg=PT73 }}</ref> and hence Canopus became ''α Carinae'' ([[Latinisation of names|Latinised]] to ''Alpha Carinae''). It is listed in the [[Bright Star Catalogue]] as HR 2326, the [[Henry Draper Catalogue]] as HD 45348, and the [[Hipparcos catalogue]] as HIP 30438.<ref name=SIMBAD/> Flamsteed did not number this southern star, but [[Benjamin Apthorp Gould]] gave it the number 7 (7 G. Carinae) in his ''Uranometria Argentina''.<ref name=Gould1878>{{cite journal | title=Uranometria Argentina: Brightness and position of every fixed star, down to the seventh magnitude, within one hundred degrees of the South Pole; with atlas | last=Gould | first=Benjamin Apthorp | journal=Resultados del Observatorio Nacional Argentino | volume=1 | page=140 | date=1878 | bibcode=1879RNAO....1....1G }}</ref>
An occasional name seen in English is ''Soheil'', or the feminine Soheila; in Turkish is ''Süheyl'', or the feminine Süheyla, from the Arabic name for several bright stars, سهيل ''suhayl'',<ref name="hinkley63"/> and Canopus was known as Suhel {{IPAc-en|'|s|uː|h|E|l}} in medieval times.<ref name=kunitzsch/> Alternative spellings include Suhail, Souhail, Suhilon, Suheyl, Sohayl, Suhayil, Shoel, Sohil, Soheil, Sahil, Suhayeel, Sohayil, Sihel, and Sihil.<ref name="hinkley63"/> An alternative name was ''Wazn'' "weight" or ''Haḍar'' "ground", possibly related to its low position near the horizon.<ref name="hinkley63"/> Hence comes its name in the ''[[Alfonsine tables]]'', Suhel ponderosus, a Latinization of ''Al Suhayl al Wazn''.<ref name="hinkley63"/> Its Greek name was revived during the [[Renaissance]].<ref name=kunitzsch>{{cite book |last1=Kunitzsch|first1=Paul |last2=Smart|first2=Tim |date = 2006|title = A Dictionary of Modern star Names: A Short Guide to 254 Star Names and Their Derivations |edition = 2nd rev. |publisher = Sky Publishing Corporation |location = Cambridge, Massachusetts |isbn = 978-1-931559-44-7 |page = 23}}</ref>
==Observation==
[[File:Carina constellation map.svg|thumb|left|The constellation [[Carina (constellation)|Carina]] with Canopus towards the right (west)]]
The Spanish Muslim astronomer [[Ibn Rushd]] went to [[Marrakesh]] (in Morocco) to observe the star in 1153, as it was invisible in his native [[Córdoba, Spain|Córdoba]], [[Al-Andalus]]. He used the different visibility in different latitudes to argue that the [[Spherical Earth|earth is round]], following [[Spherical Earth#Aristotle|Aristotle's argument]] which held that such an observation was only possible if the earth was a relatively small sphere.<ref name=ibn_rushd>{{cite encyclopedia|first1=Juan|last1=Vernet|author-link1=Juan Vernet|first2=Julio|last2=Samsó|author-link2=Julio Samsó |title=The development of Arabic science in Andalusia |page=264|editor=[[Roshdi Rashed]]|encyclopedia=Encyclopedia of the History of Arabic Science | date=1996|publisher=Routledge|isbn=978-0-415-12410-2|oclc=912501823}}</ref>
English explorer [[Robert Hues]] brought Canopus to the attention of European observers in his 1592 work ''Tractatus de Globis'', along with [[Achernar]] and [[Alpha Centauri]], noting:<blockquote>"Now, therefore, there are but three [[First-magnitude star|Stars of the first magnitude]] that I could perceive in all those parts which are never seene here in England. The first of these is that bright Star in the sterne of [[Argo Navis|Argo]] which they call Canobus. The second is in the end of [[Eridanus (constellation)|Eridanus]]. The third is in the right foote of the [[Centaurus|Centaure]]."<ref>Knobel, p. 416.</ref></blockquote>
[[File:Vela and Surrounding Constellations (ground-based image).jpg|right|thumb|Wide angle view showing Canopus and other prominent stars with the Milky Way|alt=A field of stars against the Milky Way background with the prominent stars and constellations labelled]]
In the [[Southern Hemisphere]], Canopus and [[Sirius]] are both visible high in the sky simultaneously, and reach a [[meridian (astronomy)|meridian]] just {{val|21|u=minutes}} apart. Brighter than [[first-magnitude star|first magnitude]], Canopus can be seen by naked eye in the early twilight. Mostly visible in mid to late summer in the Southern Hemisphere, Canopus [[Culmination|culminates]] at midnight on December 27,<ref name="motz" /> and at 9 PM on February 11.<ref name="Schaaf257">Schaaf, p. 257.</ref>
When seen from latitudes south of {{DEC|37|18}} S, Canopus is a [[circumpolar star]]. Since Canopus is so far south in the sky, it never rises in mid- to far-northern latitudes; in theory the northern limit of visibility is latitude {{DEC|37|18}} north. This is just south of [[Athens]], [[Richmond, Virginia]] (USA), and [[San Francisco]], and very close to [[Seville]] and [[Agrigento]]. It is almost exactly the latitude of [[Lick Observatory]] on [[Mount Hamilton (California)|Mt. Hamilton, California]], from which it is readily visible because of the effects of elevation and [[atmospheric refraction]], which add another degree to its apparent altitude. Under ideal conditions, it can be spotted as far north as latitude {{DEC|37|31}} from the Pacific coast.<ref>D. Gieringer, "Exploring the Tropic of Canopus", ''Astronomy'', December 1985, p.24.</ref> Another northernmost record of visibility came from [[Mount Nemrut]] in Turkey, latitude {{DEC|37|59}}.<ref>{{cite web |last1=Tezel |first1=Tunç |author-link=Tunç Tezel |url=http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |title=Zodiacal Light and Nemrut Heritage |work=The World At Night (TWAN) |access-date=17 March 2014 |date=8 Oct 2013 |archive-url=https://web.archive.org/web/20140317134955/http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |archive-date=17 March 2014 |url-status=dead }}</ref> It is more easily visible in places such as the Gulf Coast and Florida, and the island of [[Crete]] (Greece) where the best season for viewing it around 9 p.m. is during late January and early February.<ref name="motz">{{cite book|last1=Motz|first1=Lloyd|last2=Nathanson|first2=Carol|title=The Constellations: An Enthusiast's Guide to the Night Sky|publisher=Aurum Press|location=London, United Kingdom|date=1991|pages=376–77|isbn=1-85410-088-2}}</ref>
Canopus has a B–V [[color index]] of +0.15—where 0 is a blue-white—indicating it is essentially white, although it has been described as yellow-white. Canopus' spectral type has been given as F0 and the incrementally warmer A9. It is less yellow than [[Altair]] or [[Procyon]], with indices measured as 0.22 and 0.42, respectively.<ref name=Hoffleit1991>{{cite book | title=Bright Star Catalogue | edition=5th Revised | last1=Hoffleit | first1=D. | last2=Warren Jr. | first2=W. H. | date=1991 | publisher=[[Centre de Données astronomiques de Strasbourg|CDS]] }}</ref> Some observers may have perceived Canopus as yellow-tinged because it is low in the sky and hence subject to atmospheric effects.<ref name="Schaaf112">Schaaf, pp. 112–13.</ref> [[Patrick Moore]] said that it never appeared anything but white to him.<ref name="moore2000">{{cite book | first1=Patrick | last1=Moore | title=Exploring the night sky with binoculars | edition=4th | publisher=Cambridge University Press | year=2000 | isbn=9780521793902 | page=[https://archive.org/details/exploringnightsk00moor/page/69 69] | url=https://archive.org/details/exploringnightsk00moor| url-access=registration }}</ref> The [[bolometric correction]] for Canopus is 0.00,<ref name=smiljanic2006/> indicating that the visual [[absolute magnitude]] and bolometric absolute magnitude are equal.
Canopus was previously proposed to be a member of the [[Scorpius–Centaurus association]], however it is not located near the subgroups of that association, and has not been included as a Sco-Cen member in kinematic studies that used [[Hipparcos]] astrometric data.<ref name="deZeeuw">{{cite journal|last1=de Zeeuw|first1=P.T. |last2=Hoogerwerf|first2=R. |last3=de Bruijne|first3=J.H.J |last4=Brown|first4=A.G.A |last5=Blaauw|first5=A. |date=1999|title=A HIPPARCOS Census of the Nearby OB Associations |journal=The Astronomical Journal |volume=117 |issue=1 |pages=354–399|bibcode=1999AJ....117..354D |doi=10.1086/300682|arxiv = astro-ph/9809227 |s2cid=16098861 }}</ref> Canopus is not thought to be a member of any nearby young stellar groups.<ref name=mamajek>{{cite journal | url=https://figshare.com/articles/Canopus_B_A_Candidate_Common_Proper_Motion_Companion_to_the_Second_Brightest_Star/1132696 | title=Canopus B: A Candidate Common Proper Motion Companion to the Second Brightest Star | last=Mamajek | first=Eric | year=2014 | publisher=Figshare | doi=10.6084/m9.figshare.1132696.v3 | access-date=2020-09-10 }}</ref> In 2014, astronomer Eric Mamajek reported that an extremely magnetically active M dwarf (having strong coronal X-ray emission), 1.16 degrees south of Canopus, appears to share a [[common proper motion]] with Canopus. The projected separation of the M dwarf 2MASS J06234738-5351131 ("Canopus B") is approximately 1.9 parsecs. However, despite this large separation, it is still within the estimated tidal radius (2.9 parsecs) for the massive star Canopus.<ref name="mamajek"/>
No star closer than Canopus is more luminous than it, and it has been the brightest star in Earth's night sky during three epochs over the past four million years. Other stars appear brighter only during relatively temporary periods, during which they are passing the Solar System much closer than Canopus. About 90,000 years ago, [[Sirius]] moved close enough that it became brighter than Canopus, and that will remain so for another 210,000 years. But in 480,000 years, as Sirius moves further away and appears fainter, Canopus will once again be the brightest, and will remain so for a period of about 510,000 years.<ref name="tomkin98">{{cite journal|last=Tomkin|first=Jocelyn|date=April 1998|title=Once and Future Celestial Kings|journal=Sky and Telescope|volume=95|issue=4|pages=59–63|bibcode=1998S&T....95d..59T}}</ref><!-- this all comes from same paper -->
===Role in navigation===
The southeastern wall of the [[Kaaba]] in [[Mecca]] is aligned with the rising point of Canopus, and is also named ''Janūb''.<ref>{{cite book|author=George Nicholas Atiyeh|title=The Book in the Islamic World: The Written Word and Communication in the Middle East|url=https://books.google.com/books?id=t4LEfpCW_kQC|date=1 January 1995|publisher=SUNY Press|isbn=978-0-7914-2473-5}}</ref> The [[Negev Bedouin|Bedouin]] people of the [[Negev]] and [[Sinai Peninsula|Sinai]] knew Canopus as ''Suhayl'', and used it and [[Polaris]] as the two principal stars for navigation at night. Because it disappears below the horizon in those regions, it became associated with a changeable nature, as opposed to always-visible Polaris, which was circumpolar and hence 'steadfast'.<ref>{{cite journal |last=Bailey |first=Clinton |date=1974 |title=Bedouin Star-Lore in Sinai and the Negev |journal=Bulletin of the School of Oriental and African Studies, University of London |volume=37 |issue=3 |pages=580–96 |type=abstract |doi=10.1017/S0041977X00127491 |jstor=613801|s2cid=131527348 }}</ref>
The south [[celestial pole]] can be approximately located using Canopus and another bright star, [[Achernar]], as the three make an [[equilateral triangle]]. Canopus sits on an imaginary line that extends {{DEC|36}} one way to Sirius and {{DEC|37}} to the south celestial pole.<ref>{{Cite book| last1 = Heifetz| first1 = Milton| last2 = Tirion| first2 = Wil| title = A Walk Through the Heavens: A Guide to Stars and Constellations and Their Legends | date = 2007| publisher = [[Cambridge University Press]]| location = Cambridge | page = 38 | isbn=978-1-139-46138-2}}</ref>
Canopus's brightness and location well off the [[ecliptic]] make it useful for space navigation. Many spacecraft carry a special camera known as a "Canopus [[star tracker|Star Tracker]]" plus a Sun sensor for [[Orientation (geometry)|attitude]] determination. [[Mariner 4]] used Canopus for [[Spin-stabilisation|second axis stabilisation]] (after locking on the Sun) in 1964, the first time a star had been used.<ref>{{cite book |last1=United States. National Aeronautics and Space Administration. Scientific and Technical Information Division |title=Astronautics and Aeronautics, 1964: Chronology on Science, Technology and Policy |date=1965 |publisher=Scientific and Technical Information Division, National Aeronautics and Space Administration |page=398 |url=https://books.google.com/books?id=ckkCAAAAIAAJ&pg=PA398}}</ref>
==Spectrum==
Canopus was little-studied by western scientists before the 20th century. It was given a spectral class of F in 1897, an early use of this extension to [[Secchi class]] I, applied to those stars where the hydrogen lines are relatively weak and the [[calcium K line]] relatively strong.<ref>{{cite journal |bibcode=1897ApJ.....6..349P |title=Spectra of bright southern stars |last1=Pickering |first1=E. C. |last2=Cannon |first2=A. J. |journal=The Astrophysical Journal |year=1897 |volume=6 |page=349 |doi=10.1086/140407 }}</ref> It was given as a standard star of F0 in the [[Henry Draper Catalogue]], with the spectral type F0 described as having hydrogen lines half the strength of an A0 star and the calcium K line three times as strong as Hδ.<ref name=hd>{{cite journal |bibcode=1918AnHar..92....1C |title=The Henry Draper catalogue : 4h, 5h and 6h |last1=Cannon |first1=Annie Jump |last2=Pickering |first2=Edward Charles |journal=Annals of Harvard College Observatory |year=1918 |volume=92 |page=1 }}</ref> American astronomer [[Jesse L. Greenstein|Jesse Greenstein]] was interested in stellar spectra and used the newly built [[Otto Struve Telescope]] at [[McDonald Observatory]] to analyze the star's spectrum in detail.<ref>{{cite book |last1=Trimble |first1=Virginia | first2= Thomas R. |last2=Williams | first3= Katherine | last3=Bracher| first4= Richard | last4=Jarrell| first5=Jordan D.| last5= Marché| first6=F. Jamil | last6=Ragep |title=Biographical Encyclopedia of Astronomers |date=2007 |publisher=Springer Science & Business Media |location=New York, New York |isbn=978-0-387-30400-7 |page=438 |url=https://books.google.com/books?id=t-BF1CHkc50C&pg=PA438}}</ref> In a 1942 paper, he reported that the spectrum is dominated by strong broad hydrogen lines. There are also [[absorption line]]s of carbon, nitrogen, oxygen, sulphur, iron, and many ionised metals.<ref name=greenstein1942>{{cite journal |bibcode=1942ApJ....95..161G |title=The Spectrum of α Carinae |last1=Greenstein |first1=Jesse L. |journal=The Astrophysical Journal |year=1942 |volume=95 |page=161 |doi=10.1086/144382 }}</ref> It was studied in the [[ultraviolet]] by an early astronomical satellite, [[Gemini XI]] in 1966. The UV spectra were considered to be consistent with an F0 [[Supergiant star|supergiant]] having a temperature of {{val|6,900|fmt=commas|u=K}}, the accepted parameters for Canopus at the time.<ref name=kondo1970>{{cite journal |bibcode=1970ApJ...159..927K |title=Ultraviolet Spectrophotometry of Canopus from Gemini XI |last1=Kondo |first1=Y. |last2=Henize |first2=K. G. |last3=Kotila |first3=C. L. |journal=The Astrophysical Journal |year=1970 |volume=159 |page=927 |doi=10.1086/150370 }}</ref> New Zealand-based astronomers [[John Hearnshaw]] and Krishna Desikachary examined the spectrum in greater detail, publishing their results in 1982.<ref>{{cite journal |title=The spectrum of Canopus | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 198 | year= 1982 | issue= 2 | pages= 311–320 | doi= 10.1093/mnras/198.2.311 | bibcode=1982MNRAS.198..311H| doi-access= free }}</ref><ref>{{cite journal |title=The spectrum of Canopus II - Analysis and composition | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 201 | year= 1982 | issue= 3 | pages= 707–721 | doi= 10.1093/mnras/201.3.707 | bibcode=1982MNRAS.201..707D| doi-access= free }}</ref>
When [[luminosity class]]es were added to the MK spectral classification scheme, Canopus was assigned class Iab indicating an intermediate luminosity supergiant. This was based on the relative strengths of certain spectral lines understood to be sensitive to the luminosity of a star.<ref name=devaucoleurs>{{cite journal|title=Spectral types and luminosities of B, A and F southern stars|author=de Vaucouleurs, A.|journal=Monthly Notices of the Royal Astronomical Society|volume=117|page=449|date=1957|issue=4|bibcode=1957MNRAS.117..449D|doi=10.1093/mnras/117.4.449|doi-access=free}}</ref> In the [[Bright Star Catalogue]] 5th edition it is given the spectral class F0II, the luminosity class indicating a [[bright giant]].<ref name=bsc>{{cite book |bibcode=1991bsc..book.....H |year=1991 |title=The Bright star catalogue |last1=Hoffleit |first1=Dorrit |last2=Jaschek |first2=Carlos }}</ref> [[Balmer line]] profiles and oxygen line strengths indicate the size and luminosity of Canopus.<ref name=kovtyukh2012>{{cite journal |bibcode=2012MNRAS.423.3268K |title=Accurate luminosities from the oxygen λ7771-4 Å triplet and the fundamental parameters of F-G supergiants |last1=Kovtyukh |first1=V. V. |last2=Gorlova |first2=N. I. |last3=Belik |first3=S. I. |journal=Monthly Notices of the Royal Astronomical Society |year=2012 |volume=423 |issue=4 |page=3268 |doi=10.1111/j.1365-2966.2012.21117.x |arxiv=1204.4115 |s2cid=118683158 }}</ref>
When the effects of stellar rotation speed on spectral lines are accounted for, the MK spectral class of Canopus is adjusted to A9II.<ref name=perkins/> Its spectrum consists mostly of absorption lines on a visible [[continuous spectrum|continuum]], but some emission has been detected. For example, the [[calcium K line]] have weak emission wings on each side of the strong central absorption line, first observed in 1966. The emission line profiles are usually correlated with the luminosity of the star as described by the [[Wilson-Bappu effect]], but in the case of Canopus they indicate a luminosity much lower than that calculated by other methods.<ref name=warner1966>{{cite journal|title=CA II emission in the spectrum of Canopus|journal=The Observatory |volume=86 |pages=82|date=April 1966|last=Warner |first=B. |bibcode=1966Obs....86...82W }}</ref> More detailed observations have shown that the emission line profiles are variable and may be due to [[plage (astronomy)|plage]] areas on the surface of the star. Emission can also be found in other lines such as the h and k lines of ionised magnesium.<ref name=bappu1984>{{cite journal |bibcode=1984BASI...12..196B |title=CA II K emission in Canopus |last1=Bappu |first1=M. K. V. |last2=Mekkaden |first2=M. V. |last3=Rao |first3=N. K. |journal=Bulletin of the Astronomical Society of India |year=1984 |volume=12 |page=196 }}</ref>
==Distance==
Before the launch of the [[Hipparcos]] satellite telescope, distance estimates for Canopus varied widely, from 96 [[light-year]]s to 1200 light-years. The closer distance was derived from parallax measurements of around {{val|33|ul=mas}}.<ref name=vandekamp1943>{{cite journal |title=Note on the Parallax of Canopus|journal=Popular Astronomy |volume=51 |date=1943 |page=172 |last=van de Kamp |first=Peter|bibcode=1943PA.....51..172V }}</ref> The larger distance derives from the assumption of a very bright [[absolute magnitude]] for Canopus.<ref name=vanzyl>{{cite book|author=J.E. van Zyl|title=Unveiling the Universe: An Introduction to Astronomy|url=https://books.google.com/books?id=Cj7uBwAAQBAJ&pg=PA184|date=6 December 2012|publisher=Springer Science & Business Media|isbn=978-1-4471-1037-8|pages=184–}}</ref>
Hipparcos established Canopus as being {{val|310|u=light-years}} ({{val|95|ul=parsecs}}) from the [[Solar System]]; this is based on its 2007 [[parallax]] measurement of {{Val|10.43|0.53|ul=mas}}.<ref name="van Leeuwen2007"/> At 95 parsecs, the [[interstellar extinction]] for Canopus is low at 0.26 magnitudes.<ref name=DomicianoDeSouza/> Canopus is too bright to be included in the normal observation runs of the [[Gaia satellite]] and there is no published Gaia parallax for it.<ref name=dr2>{{cite DR2}}</ref>
At present the star is drifting further away from the Sun with a [[radial velocity]] of 20 km/s. Some 3.1 million years ago it made the closest approach to the Sun at a distance of about {{convert|52.87|pc|ly|0|adj=ri0|order=flip|abbr=on|lk=off}}. Canopus is orbiting the Milky Way with a heliocentric velocity of 24.5 km/s and a low [[orbital eccentricity|eccentricity]] of 0.065.<ref name=Anderson2012>{{citation | last1=Anderson | first1=E. | last2=Francis | first2=Ch. | title=XHIP: An extended hipparcos compilation | journal=Astronomy Letters | volume=38 | issue=5 | pages=331 | year=2012 | bibcode=2012AstL...38..331A | arxiv=1108.4971 | doi=10.1134/S1063773712050015 | s2cid=119257644 | postscript=. }}</ref>
==Physical characteristics==
[[File:Constellation_Carina.jpg|thumb|right|upright|Canopus is the brightest star in the constellation of Carina (top).]]
The [[absorption line]]s in the spectrum of Canopus shift slightly with a period of {{val|6.9|u=days}}. This was first detected in 1906 and the [[doppler effect|Doppler]] variations were interpreted as orbital motion.<ref name=curtis1907>{{cite journal |bibcode=1907PASP...19R.259C |title=The orbits of the spectroscopic binaries alpha Carinae, kappa Velorum, and alpha Pavonis |last1=Curtis |first1=H. D. |journal=Publications of the Astronomical Society of the Pacific |year=1907 |volume=19 |page=259 |doi=10.1086/121781 }}</ref> An orbit was even calculated, but no such companion exists and the small radial velocity changes are due to movements in the atmosphere of the star. The maximum observed [[radial velocities]] are only 0.7 to {{val|1.6|ul=km/s}}. Canopus also has a magnetic field that varies with the same period, detected by the [[Zeeman splitting]] of its spectral lines.<ref name=weiss1986>{{cite journal |bibcode=1986A&A...160..243W | title=The magnetic field of Canopus | last=Weiss | first=W. W. | journal= Astronomy and Astrophysics |volume= 160|pages= 243–250 | year=1986}}</ref> Canopus is bright at [[microwave]] wavelengths, one of the few F-class stars to be detected by radio.<ref name=gudel2002>{{cite journal |bibcode=2002ARA&A..40..217G |title=Stellar Radio Astronomy: Probing Stellar Atmospheres from Protostars to Giants |last1=Güdel |first1=Manuel |journal=Annual Review of Astronomy and Astrophysics |year=2002 |volume=40 |pages=217–261 |doi=10.1146/annurev.astro.40.060401.093806 |arxiv=astro-ph/0206436 |s2cid=53633983 }}</ref> The [[rotation period]] of the star is not accurately known, but may be over three hundred days.<ref name=Testa2004>{{cite journal | title=The Density of Coronal Plasma in Active Stellar Coronae | last1=Testa | first1=Paola | last2=Drake | first2=Jeremy J. | last3=Peres | first3=Giovanni | journal=The Astrophysical Journal | volume=617 | issue=1 | pages=508–530 | date=December 2004 | doi=10.1086/422355 | arxiv=astro-ph/0405019 | bibcode=2004ApJ...617..508T | s2cid=17532089 }}</ref> The [[projected rotational velocity]] has been measured at 9 km/s.<ref name=ayres2018/>
An early [[Interferometry|interferometric]] measurement of its [[angular diameter]] in 1968 gave a [[Limb darkening|limb-darkened]] value of {{val|6.86|ul=mas}}, close to the accepted modern value.<ref>{{cite journal |bibcode=1968ARA&A...6...13B |title=Measurement of Stellar Diameters |last1=Brown |first1=R. Hanbury |journal=Annual Review of Astronomy and Astrophysics |year=1968 |volume=6 |page=13 |doi=10.1146/annurev.aa.06.090168.000305 }}</ref> [[Very-long-baseline interferometry]] has been used to calculate Canopus' angular diameter at {{val|6.9|ul=mas}}. Combined with distance calculated from its Hipparcos parallax, this gives it a radius of 71 times [[Solar radius|that of the Sun]].<ref name=vlti/> If it were at the centre of the Solar System, it would extend 90% of the way to the orbit of [[Mercury (planet)|Mercury]].<ref name=Kalerstars>{{cite web|url=http://stars.astro.illinois.edu/sow/canopus.html|title=Canopus|last=Kaler|first=Jim|work=Stars|publisher=University of Illinois|access-date=8 July 2012|date=26 June 2009}}</ref> The radius and temperature relative to the Sun means that it is 10,700 times more luminous than the Sun, and its position in the [[H-R diagram]] relative to theoretical [[stellar evolution|evolutionary]] tracks means that it is {{Val|8.0|0.3}} times as massive as the Sun.<ref name=vlti/> Measurements of its shape find a 1.1° departure from spherical symmetry.<ref name=cruzalebes2015>{{cite journal |bibcode=2015MNRAS.446.3277C |title=Departure from centrosymmetry of red giants and supergiants measured with VLTI/AMBER |last1=Cruzalèbes |first1=P. |last2=Jorissen |first2=A. |last3=Chiavassa |first3=A. |last4=Paladini |first4=C. |last5=Rabbia |first5=Y. |last6=Spang |first6=A. |journal=Monthly Notices of the Royal Astronomical Society |year=2015 |volume=446 |issue=4 |page=3277 |doi=10.1093/mnras/stu2382 |doi-access=free }}</ref>
Canopus is a source of [[X-ray astronomy|X-rays]], which are probably produced by its corona, magnetically heated to several million [[Kelvin]]. The temperature has likely been stimulated by fast rotation combined with strong convection percolating through the star's outer layers.<ref name=ness>{{cite journal|bibcode=2004A&A...427..667N|title=On the sizes of stellar X-ray coronae|journal=Astronomy and Astrophysics|volume=427|issue=2|pages=667–683|last1=Ness|first1=J.-U.|last2=Güdel|first2=M.|last3=Schmitt|first3=J. H. M. M.|last4=Audard|first4=M.|last5=Telleschi|first5=A.|year=2004|doi=10.1051/0004-6361:20040504|arxiv = astro-ph/0407231 |s2cid=11468731}}</ref> The soft X-ray sub-coronal X-ray emission is much weaker than the hard X-ray coronal emission. The same behaviour has been measured in other F-class supergiants such as [[α Persei]] and is now believed to be a normal property of such stars.<ref name=ayres2018/>
== Evolution ==
The spectrum of Canopus indicates that it has exhausted its core hydrogen and [[stellar evolution|evolved]] away from the [[main sequence]], where it spent some 30 million years of its existence as a blue-white star <!-- source suggests B2V but may be too exact --> of around 10 solar masses.<ref>{{cite journal |last1=Peimbert |first1=M. |last2=Wallerstein | first2= G.| last3= Pilachowski | first3= C. A. |title=An upper limit for the deuterium abundance in Canopus |journal=Astronomy and Astrophysics |date=1981 |volume=104 |issue=1 |pages=72–74 | bibcode=1981A&A...104...72P}}</ref> The position of Canopus in the [[H–R diagram]] indicates that it is currently in the core-helium burning phase.<ref name=vlti/> It is an intermediate mass star that has left the [[red-giant branch]] before its core became [[degenerate matter|degenerate]] and is now in a [[blue loop]].<ref name=desouza>{{Cite journal | last1 = Domiciano De Souza | first1 = A. | last2 = Bendjoya | first2 = P. | last3 = Vakili | first3 = F. | last4 = Millour | first4 = F. | last5 = Petrov | first5 = R. G. | title = Diameter and photospheric structures of Canopus from AMBER/VLTI interferometry | doi = 10.1051/0004-6361:200810450 | journal = Astronomy and Astrophysics | volume = 489 | issue = 2 | pages = L5–L8 | year = 2008 |bibcode = 2008A&A...489L...5D | url = https://hal.archives-ouvertes.fr/hal-00316994/document | doi-access = free }}</ref> Models of stellar evolution in the blue loop phase show that the length of the blue loop is strongly affected by rotation and mixing effects inside the star. It is difficult to determine whether a star is currently evolving towards hotter temperature or returning to cooler temperatures, since the evolutionary tracks for stars with different masses overlap during the blue loops.<ref name=smiljanic2006>{{cite journal |bibcode=2006A&A...449..655S |title=CNO in evolved intermediate mass stars |last1=Smiljanic |first1=R. |last2=Barbuy |first2=B. |last3=De Medeiros |first3=J. R. |last4=Maeder |first4=A. |journal=Astronomy and Astrophysics |year=2006 |volume=449 |issue=2 |page=655 |doi=10.1051/0004-6361:20054377 |arxiv=astro-ph/0511329 |s2cid=3711409 }}</ref>
Canopus lies on the warm side of the [[instability strip]] and does not pulsate like [[Cepheid variables]] of a similar luminosity.<ref name=ayres2011>{{cite journal |doi=10.1088/0004-637X/738/2/120 |title=The Curious Case of the Alpha Persei Corona: A Dwarf in Supergiant's Clothing? |year=2011 |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |volume=738 |issue=2 |page=120 |bibcode=2011ApJ...738..120A |doi-access=free }}</ref> However its atmosphere does appear to be unstable, showing strong signs of convection.<ref name=smiljanic2006/>
Canopus may not be massive enough for its [[nuclear fusion|fusion]] chain to reach iron and trigger a core collapse and subsequent [[supernova]], instead eventually becoming a neon-oxygen [[white dwarf]].<ref name=Kalerstars/>
==Cultural significance ==
Canopus was known to the ancient Mesopotamians and given the name ''NUN-ki'' and represented the city of [[Eridu]] in the ''Three Stars Each'' [[Babylonian star catalogues]] and later [[MUL.APIN]] around 1100 BC.<ref>{{cite journal | last = Rogers | first = John H. | date = 1998 | title = Origins of the Ancient Constellations: I. The Mesopotamian Traditions | journal = Journal of the British Astronomical Association | volume = 108 | issue = 1 | pages = 9–28 | bibcode = 1998JBAA..108....9R}}</ref> Today, the star [[Sigma Sagittarii]] is known by the common name Nunki.<ref name=allen>{{citation | page=359 | first1=Richard Hinckley | last1=Allen | title=Star Names, their lore and meaning}}</ref>
Canopus was not visible to the mainland [[Ancient Greece|ancient Greeks]] and [[Roman Empire|Romans]]; it was, however, visible to the [[ancient Egypt]]ians.<ref name="Schaaf107">Schaaf, p. 107.</ref> Hence [[Aratus]] did not write of the star as it remained below the horizon, while [[Eratosthenes]] and [[Ptolemy]]—observing from [[Alexandria]]—did, calling it ''Kanōbos''.<ref name=ridpathCr>{{cite web| url=http://www.ianridpath.com/startales/carina.htm | title=Carina |last1=Ridpath|first1=Ian|publisher=self-published |work=Star Tales | access-date= 10 December 2015}}</ref> An [[Egypt]]ian priestly poet in the time of [[Thutmose III]] mentions the star as ''Karbana,'' "the star which pours his light in a glance of fire, when he disperses the morning dew."<ref name="hinkley63" /> Under the [[Ptolemies]], the star was known as ''Ptolemaion'' ([[Ancient Greek|Greek]]: Πτολεμαῖον) and its [[acronychal rising]] marked the date of the Ptolemaia festival, which was held every four years, from 262 to 145 BC.<ref>[[Martianus Capella]] 7.838, {{cite journal | last1 = Hazzard | last2 = Fitzgerald | year = 1991 | title = The Regulation of the Ptolemeia | journal = Journal of the Royal Astronomical Society of Canada | volume = 85 | pages = 6–23 |bibcode = 1991JRASC..85....6H }}; Hazzard. 2000. ''Imagination of a Monarchy: Studies in Ptolemaic Propaganda'', 34–36.</ref>
[[File:Statue of Averroes in Córdoba, Spain.jpg|thumb|upright|[[Averroes]], who used his 1153 observation of Canopus in [[Marrakesh]] while the star was invisible in his native Spain as an argument that the [[Spherical Earth|earth is round]].<ref name=ibn_rushd/>]]
===India===
In Indian [[Vedas|Vedic literature]], Canopus is associated with the sage [[Agastya]], one of the ancient [[siddhar]]s and [[rishi]]s (the others are associated with the stars of the [[Big Dipper]]).<ref name="Frawley 1993">{{cite book|last=Frawley|first=David|title=Gods, Sages and Kings: Vedic Secrets of Ancient Civilization|publisher=Motilal Banarsidass |location=New Delhi, India|date=1993}}</ref> To Agastya, the star is said to be the 'cleanser of waters', and its rising coincides with the calming of the waters of the [[Indian Ocean]]. It is thus considered the son of [[Pulastya]], son of [[Brahma]]. Canopus is described by [[Pliny the Elder]] and [[Gaius Julius Solinus]] as the largest, brightest and only source of [[starlight]] for navigators near [[Tamraparni]] island (ancient Sri Lanka) during many nights.<ref>{{cite book |last1=Pridham |first1=Charles |title=An Historical, Political, and Statistical Account of Ceylon and Its Dependencies |date=1849 |publisher=T. and W. Boone |page=7 |url=https://books.google.com/books?id=O4aqHOMSJdYC&pg=PR19-IA5|language=en}}</ref><ref name="Frawley 1993"/><ref>{{cite book |last1=Elder |first1=Pliny the |title=Delphi Complete Works of Pliny the Elder (Illustrated) |date=2015 |publisher=Delphi Classics |url=https://books.google.com/books?id=OrJ0CgAAQBAJ&pg=PA343|language=en}}</ref>
===China===
Canopus was described as Shou Xing, the Star of Longevity, in the ''Shiji'' ([[Records of the Grand Historian]]) completed in 94 BC by Chinese historian [[Sima Qian]].<ref name=fong83>{{cite journal | title=The Iconography of the Popular Gods of Happiness, Emolument, and Longevity (Fu Lu Shou) | first=Mary H. |last=Fong | journal=Artibus Asiae | volume= 44 | issue= 2/3 | year=1983| pages= 159–199 | doi= 10.2307/3249596| jstor=3249596 }}</ref> Drawing on sources from the [[Warring States period]], he noted it to be the southern counterpart of [[Sirius]],<ref name="IDP"/> and wrote of a sanctuary dedicated to it established by Emperor [[Qin Shi Huang]] between 221 and 210 BC. During the [[Han dynasty]], the star was auspicious, its appearance in the southern sky heralding peace and absence war.<ref name=fong83/> From the imperial capital [[Chang'an]], the star made a low transit across the southern sky, indicating true south to observers, and was often obscured by clouds.<ref name=baumann19>{{cite journal | title=The White Old Man: Géluk-Mongolian Canopus Allegory and the Existence of God | first=Brian | last=Baumann | journal= Central Asiatic Journal | volume= 62 | issue= 1 | year=2019| pages= 35–68 | doi=10.13173/centasiaj.62.1.0035| s2cid=213083544 }}</ref> During this time it was also equated with [[Old Man of the South Pole]] (in {{zh|c=南极老人|p=Nanji Lǎorén}})<ref name=fong83/> Under this name, Canopus appears (albeit misplaced northwards) on the medieval Chinese manuscript the [[Dunhuang Star Chart]], although it cannot be seen from the Chinese capital of [[Chang'an]].<ref name="IDP">{{cite journal|bibcode=2009JAHH...12...39B|arxiv=0906.3034|title=The Dunhuang Sky: A Comprehensive Study of the Oldest Known Star Atlas|volume=12|issue=1|pages=39–59|last1=Bonnet-Bidaud|first1=Jean-Marc |last2=Praderie|first2=Françoise |last3=Whitfield|first3=Susan |author-link=Susan Whitfield |journal=The International Dunhuang Project: The Silk Road Online|year=2009}}</ref> The Chinese astronomer [[Yi Xing]] had journeyed south to chart Canopus and other far southern stars in 724 AD.<ref>{{cite book|last=Needham|first=Joseph|title=Science and Civilisation in China: Volume 3, Mathematics and the Sciences of the Heavens and the Earth|publisher=Cambridge University Press|location=Cambridge, United Kingdom|date=1959|pages=274|isbn=0521058015}}</ref> Its personification as the Old Man Star was popularised in the [[Tang Dynasty]], where it appeared often in poetry and memorials. Later still, during the [[Ming Dynasty]], the star was established as one of the [[Sanxing (deities)|Three Stars]] (Fu Lo Shou), appearing frequently in art and literature of the time.<ref name=fong83/> This symbolism spread into neighbouring cultures in Asia.<ref name=baumann19/>
In Japan, Canopus is known as ''Mera-boshi'' and ''Roujin-sei'' (the old man star),<ref>{{cite conference |url=http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |title=Stellar Iconology and Astronomical Folklore in Japan |author=Takao Ibaraki |book-title=International Planetarium Society (IPS) Conferences 1996 |publisher=International Planetarium Society |location=Osaka |date=14 July 1996 |access-date=25 February 2012 |url-status=dead |archive-url=https://web.archive.org/web/20120326195757/http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |archive-date=2012-03-26 }}</ref> and in Mongolia, it was personified as the White Old Man.<ref name=fong83/> Although the link was known in Tibet, with names such as ''Genpo karpo'' (''Rgan po dkar po'') or ''Genkar'' (''Rgan dkar'') "White Old Man", the symbolism was not popular. Instead, Canopus was more commonly named ''Karma Rishi སྐར་མ་རི་ཥི།'', derived from Indian mythology. Tibetans celebrated the star's heliacal rising with ritual bathing and associated it with morning dew.<ref name=baumann19/>
===Polynesia===
Bright stars were important to the ancient [[Polynesian culture|Polynesians]] for navigation between the many islands and atolls of the Pacific Ocean. Low on the horizon, they acted as stellar compasses to assist mariners in charting courses to particular destinations. Canopus served as the southern wingtip of a "Great Bird" constellation called ''Manu'', with Sirius as the body and [[Procyon]] the northern wingtip, which divided the Polynesian night sky into two hemispheres.<ref name="Holberg">{{cite book | last=Holberg | first=J.B. | title=Sirius: Brightest Diamond in the Night Sky | date=2007 | publisher=Praxis Publishing | location=Chichester, UK | isbn=978-0-387-48941-4 | pages=[https://archive.org/details/siriusbrightestd0000holb/page/25 25–26] | url=https://archive.org/details/siriusbrightestd0000holb/page/25 }}</ref> The [[Hawaiian people]] called Canopus ''Ke Alii-o-kona-i-ka-lewa'', "The chief of the southern expanse"; it was one of the stars used by [[Hawaiʻiloa]] and Ki when they traveled to the [[Southern Ocean]].{{sfn|Makemson|1941|p=198}} The [[Māori people]] of [[New Zealand|New Zealand/Aotearoa]] had several names for Canopus. ''[[Ariki]]'' ("High-born"), was known as a solitary star that appeared in the east, prompting people to weep and chant.{{sfn|Makemson|1941|p=201}} They also named it ''[[Atutahi]]'', ''Aotahi'' or ''Atuatahi'', "Stand Alone".<ref>p. 419, [https://books.google.com/books?id=p7dR2w1Wv2sC ''Mythology: Myths, Legends and Fantasies''], Janet Parker, Alice Mills, Julie Stanton, Durban, Struik Publishers, 2007.</ref> Its solitary nature indicates it is a ''[[Tapu (Polynesian culture)|tapu]]'' star, as ''tapu'' people are often solitary. Its appearance at the beginning of the ''Maruaroa'' season foretells the coming winter; light rays to the south indicate a cold wet winter, and to the north foretell a mild winter. Food was offered to the star on its appearance.<ref name="Best22">{{cite book|last=Best|first=Elsdon|title=Astronomical Knowledge of the Maori: Genuine and Empirical|publisher=Dominion Museum|location=Wellington, New Zealand|date=1922|pages=34–35|url=http://nzetc.victoria.ac.nz/tm/scholarly/tei-BesAstro-t1-body-d1-d6-d4.html}}</ref> This name has several mythologies attached to it. One story tells of how Atutahi was left outside the basket representing the [[Milky Way]] when [[Tāne]] wove it. Another related myth about the star says that Atutahi was the first-born child of [[Rangi and Papa|Rangi]], who refused to enter the Milky Way and so turned it sideways and rose before it. The same name is used for other stars and constellations throughout Polynesia.{{sfn|Makemson|1941|pp=200–202}} ''Kapae-poto'', "Short horizon", referred to it rarely setting as seen in New Zealand;{{sfn|Makemson|1941|p=217}} ''Kauanga'' ("Solitary") was the name for Canopus only when it was the last star visible before sunrise.{{sfn|Makemson|1941|p=218}} The people of the [[Society Islands]] had two names for Canopus, as did the [[Tuamotu]] people. The Society Islanders called Canopus ''Taurua-e-tupu-tai-nanu'', "Festivity-whence-comes-the-flux-of-the-sea", and ''Taurua-nui-o-te-hiti-apatoa'' "Great-festivity-of-the-border-of-the-south",{{sfn|Makemson|1941|p=259}} and the Tuamotu people called the star ''Te Tau-rari'' and ''Marere-te-tavahi'', the latter said to be the true name for the former, "He-who-stands-alone".{{sfn|Makemson|1941|p=229}}
===Africa===
In the [[Guanches|Guanche]] mythology of the island of [[Tenerife]] (Spain), the star Canopus was linked with the goddess [[Chaxiraxi]].<ref name="Rumeu">{{cite book|author=Antonio Rumeu de Armas|title=La conquista de Tenerife, 1494–1496|url=https://books.google.com/books?id=Ck4BAAAAMAAJ|year=1975|publisher=Aula de Cultura de Tenerife|isbn=9788450071078}}</ref>
The [[Tswana people]] of [[Botswana]] knew Canopus as ''Naka''. Appearing late in winter skies, it heralded increasing winds and a time when trees lose their leaves. Stock owners knew it was time to put their sheep with rams.<ref>{{cite journal|last=Clegg|first=Andrew|date=1986|title=Some Aspects of Tswana Cosmology|journal=Botswana Notes and Records|volume=18|pages=33–37|jstor=40979758 }}</ref> In southern Africa, the Sotho, Tswana and Venda people called Canopus ''Naka'' or ''Nanga'', “the Horn Star”, while the Zulu and Swazi called it ''inKhwenkwezi'' "Brilliant star". It appears in the predawn sky in the third week of May. According to the Venda, the first person to see Canopus would blow a ''phalaphala'' horn from the top of a hill, getting a cow for a reward. The Sotho chiefs also awarded a cow, and ordered their medicine men to roll bone dice and read the fortune for the coming year.<ref name=snedegar95>{{cite journal |last1=Snedegar |first1=K.V. |title=Stars and seasons in Southern Africa |journal=Vistas in Astronomy |date=1995 |volume=39 |issue=4 |pages=529–38 |doi=10.1016/0083-6656(95)00008-9|bibcode=1995VA.....39..529S }}</ref> To the [[ǀXam language|ǀXam]]-speaking [[Bushmen]] of South Africa, Canopus and Sirius signalled the appearance of termites and flying ants. They also believed that stars had the power to cause death and misfortune, and they would pray to [[Sirius]] and Canopus in particular to impart good fortune or skill.<ref>{{cite journal| title="The Sky's Things", <nowiki>|</nowiki>xam Bushman 'Astrological Mythology' as recorded in the Bleek and Lloyd Manuscripts |last1=Hollman|first1=J. C.|journal=African Sky|volume= 11|page=8 |bibcode=2007AfrSk..11....8H|year = 2007 }}</ref> The [[ǃKung people]] of the [[Kalahari Desert]] in Botswana held Canopus and Capella to be the horns of ''tshxum'' (the Pleiades), the appearance of all three marking the end of the dry season and start of the rainy season.<ref>{{cite journal |last1=Marshall |first1=Lorna |title=Two Ju/ wa constellations |journal=Botswana Notes & Records |date=1975 |volume=7 |issue=1 |pages=153–159 | issn=0525-5090 |url=https://journals.co.za/docserver/fulltext/botnotes/7/1/548.pdf?expires=1590793041&id=id&accname=guest&checksum=3204085F9555AD9D083799E1F38E3AED}}</ref>
===Americas===
The [[Navajo]] observed the star and named it ''Maʼii Bizòʼ'', the “Coyote Star”. According to legend, Maʼii (Coyote) took part in the naming and placing of the star constellations during
the creation of the universe. He placed Canopus directly south, naming it after himself.<ref name="Maryboy">Maryboy, Nancy D. (2004). ''A Guide to Navajo Astronomy.'' Indigenous Education Institute : Bluff, Utah.</ref>
The [[Kalapalo]] people of [[Mato Grosso]] state in Brazil saw Canopus and [[Procyon]] as ''Kofongo'' "Duck", with [[Castor (star)|Castor]] and [[Pollux (star)|Pollux]] representing his hands. The asterism's appearance signified the coming of the rainy season and increase in [[manioc]], a food staple fed to guests at feasts.<ref name="basso87">{{cite book|last=Basso|first=Ellen B. |title=In Favor of Deceit: A Study of Tricksters in an Amazonian Society|publisher=University of Arizona Press|location=Tucson, Arizona|date=1987|page=[https://archive.org/details/infavorofdeceits0000bass/page/360 360]|isbn=0816510229|url=https://archive.org/details/infavorofdeceits0000bass|url-access=registration}}</ref>
===Australia===
Canopus is identified as the moiety ancestor ''Waa'' "Crow" to some [[Koori]] people in southeastern Australia.<ref>{{cite book|last=Mudrooroo|title=Aboriginal mythology: an A-Z spanning the history of aboriginal mythology from the earliest legends to the present day|publisher=HarperCollins|location=London|date=1994|page=27|isbn=1-85538-306-3}}</ref> The Boorong people of northwestern Victoria recalled that ''War'' (Canopus) was the brother of ''Warepil'' (Sirius), and that he brought fire from the heavens and introduced it to humanity. His wife was ''Collowgullouric War'' ([[Eta Carinae]]).<ref name=hamacher10>{{cite journal|last1=Hamacher|first1=Duane W. |last2=Frew|first2=David J. |date=2010|title= An Aboriginal Australian Record of the Great Eruption of Eta Carinae|journal=Journal of Astronomical History & Heritage |volume=13|issue=3|pages= 220–34|bibcode=2010JAHH...13..220H|arxiv = 1010.4610 }}</ref> The Pirt-Kopan-noot people of western Victoria tell of ''Waa'' "Crow" falling in love with a queen, ''Gneeanggar'' "Wedge-tailed Eagle" (Sirius) and her six attendants (the Pleiades). His advances spurned, he hears that the women are foraging for grubs and so transforms himself into a grub. When the women dig him out, he changes into a giant and carries her off.<ref>Mudroodoo, p. 55.</ref>
The Kulin people know Canopus as ''Lo-an-tuka''.<ref name=hamacher10/> Objects in the sky are also associated with states of being for some tribes; the Wailwun of northern New South Wales know Canopus as ''Wumba'' "deaf", alongside Mars as ''Gumba'' "fat" and Venus as ''Ngindigindoer'' "you are laughing".<ref name="noctuary">{{cite book|last=Johnson|first=Diane|title=Night skies of aboriginal Australia: a noctuary|publisher=University of Sydney|location=Darlington, New South Wales|date=1998|page=[https://archive.org/details/nightskiesofabor0000john/page/84 84]|isbn=1-86451-356-X|url-access=registration|url=https://archive.org/details/nightskiesofabor0000john/page/84}}</ref> Tasmanian aboriginal lore holds that Canopus is ''Dromerdene'', the brother of ''Moinee''; the two fought and fell out of the sky, with ''Dromerdene'' falling into Louisa Bay in southwest Tasmania.<ref name="haynes2000">{{cite book|last=Haynes|first=Ros D.|title= Astronomy and the Dreaming: The Astronomy of the Aboriginal Australians. Astronomy Across Cultures: The History of Non-Western Astronomy|publisher=Kluwer Academic Publishers|date=2000|page=57|doi=10.1007/978-94-011-4179-6_3}}</ref>
===Legacy===
[[File:HMS Glory LOC ggbain.17135.jpg|thumb|right|[[Canopus-class battleship]] HMS Glory]]
Canopus appears on the [[flag of Brazil]], symbolising the state of [[Goiás]].<ref>{{cite web
|title=Astronomy of the Brazilian Flag
|url=https://flagspot.net/flags/br_astro.html
|publisher=FOTW Flags Of The World website
}}</ref>
Two U.S. Navy [[submarine tender]]s have been named after Canopus, the [[USS Canopus (AS-9)|first]] serving from 1922 to 1942 and the [[USS Canopus (AS-34)|second]] serving from 1965 to 1994.
The [[Royal Navy]] built nine [[Canopus-class ship of the line|Canopus-class ships of the line]] in the early 19th century, and six {{Sclass|Canopus|battleship|1}}s which entered services between 1899 and 1902.
There are at least two mountains named after the star: [[Mount Canopus]] in Antarctica; and Mount Canopus or Canopus Hill in [[Tasmania]], the location of the [[Canopus Hill Observatory|Canopus Hill astronomical observatory]].
{{clear}}
==See also==
*[[List of brightest stars]]
*[[List of most luminous stars]]
*[[Dune (novel)]]
==References==
{{Reflist|30em}}
===Bibliography===
* {{cite book | last = Makemson | first = Maud Worcester | date = 1941 | publisher = [[Yale University Press]] | title = The Morning Star Rises: an account of Polynesian astronomy | bibcode = 1941msra.book.....M }}
* {{cite book |title=The Brightest Stars: Discovering the Universe through the Sky's Most Brilliant Stars |last=Schaaf |first=Fred |year=2008 |publisher=John Wiley & Sons |location=Hoboken, NJ |isbn=978-0-471-70410-2 }}
== External links ==
{{Sky|06|23|57.1099|-|52|41|44.378|310}}
{{Carina (constellation)}}
{{Portal bar|Astronomy|Stars|Spaceflight|Outer space|Solar System}}
{{Authority control}}
{{DEFAULTSORT:Canopus}}
[[Category:Canopus| ]]
[[Category:Bayer objects|Carinae, Alpha]]
[[Category:Carina (constellation)]]
[[Category:A-type bright giants]]
[[Category:Henry Draper Catalogue objects|045348]]
[[Category:Hipparcos objects|030438]]
[[Category:Bright Star Catalogue objects|2326]]
[[Category:Stars with proper names]]
[[Category:Durchmusterung objects]]
3547233edddd3de1b6a9882514b6f145cc63ca57
Template:Nowrap
10
38
92
91
2022-09-04T15:24:25Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<span class="nowrap">{{{1}}}</span><noinclude>
{{documentation}}
<!-- Categories go on the /doc page; interwikis go to Wikidata. -->
</noinclude>
5d0dc6b6d89b37f4356242404f46138a4017f015
Module:Yesno
828
39
94
93
2022-09-04T15:24:26Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'on'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'off'
or tonumber(val) == 0
then
return false
else
return default
end
end
f767643e7d12126d020d88d662a3dd057817b9dc
Module:Arguments
828
40
96
95
2022-09-04T15:24:27Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/sandbox$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
3134ecce8429b810d445e29eae115e2ae4c36c53
Module:No globals
828
41
98
97
2022-09-04T15:24:27Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local mt = getmetatable(_G) or {}
function mt.__index (t, k)
if k ~= 'arg' then
error('Tried to read nil global ' .. tostring(k), 2)
end
return nil
end
function mt.__newindex(t, k, v)
if k ~= 'arg' then
error('Tried to write global ' .. tostring(k), 2)
end
rawset(t, k, v)
end
setmetatable(_G, mt)
8ce3969f7d53b08bd00dabe4cc9780bc6afd412a
Template:Val
10
42
100
99
2022-09-04T15:24:28Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{{{{♥|safesubst:}}}#invoke:val|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
4765ec60d7235aeb2b778f12eac5cdcbd4ebab5d
Module:Val
828
43
102
101
2022-09-04T15:24:29Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- For Template:Val, output a number and optional unit.
-- Format options include scientific and uncertainty notations.
local numdot = '.' -- decimal mark (use ',' for Italian)
local numsep = ',' -- group separator (use ' ' for Italian)
local mtext = {
-- Message and other text that should be localized.
['mt-bad-exponent'] = 'exponent parameter (<b>e</b>)',
['mt-parameter'] = 'parameter ',
['mt-not-number'] = 'is not a valid number',
['mt-cannot-range'] = 'cannot use a range if the first parameter includes "e"',
['mt-need-range'] = 'needs a range in parameter 2',
['mt-should-range'] = 'should be a range',
['mt-cannot-with-e'] = 'cannot be used if the first parameter includes "e"',
['mt-not-range'] = 'does not accept a range',
['mt-cannot-e'] = 'cannot use e notation',
['mt-too-many-parameter'] = 'too many parameters',
['mt-need-number'] = 'need a number after the last parameter because it is a range.',
['mt-ignore-parameter4'] = 'Val parameter 4 ignored',
['mt-val-not-supported'] = 'Val parameter "%s=%s" is not supported',
['mt-invalid-scale'] = 'Unit "%s" has invalid scale "%s"',
['mt-both-u-ul'] = 'unit (<b>u</b>) and unit with link (<b>ul</b>) are both specified, only one is allowed.',
['mt-both-up-upl'] = 'unit per (<b>up</b>) and unit per with link (<b>upl</b>) are both specified, only one is allowed.',
}
local data_module = 'Module:Val/units'
local convert_module = 'Module:Convert'
local function valerror(msg, nocat, iswarning)
-- Return formatted message text for an error or warning.
-- Can append "#FormattingError" to URL of a page with a problem to find it.
local anchor = '<span id="FormattingError"></span>'
local body, category
if nocat or mw.title.getCurrentTitle():inNamespaces(1, 2, 3, 5) then
-- No category in Talk, User, User_talk, or Wikipedia_talk.
category = ''
else
category = '[[Category:Pages with incorrect formatting templates use]]'
end
iswarning = false -- problems are infrequent so try showing large error so editor will notice
if iswarning then
body = '<sup class="noprint Inline-Template" style="white-space:nowrap;">' ..
'[[Template:Val|<span title="' ..
msg:gsub('"', '"') ..
'">warning</span>]]</sup>'
else
body = '<strong class="error">' ..
'Error in {{[[Template:val|val]]}}: ' ..
msg ..
'</strong>'
end
return anchor .. body .. category
end
local range_types = {
-- No need for ' ' because nowrap applies to all output.
[","] = ", ",
["by"] = " by ",
["-"] = "–",
["–"] = "–",
["and"] = " and ",
["or"] = " or " ,
["to"] = " to " ,
["x"] = " × ",
["×"] = " × ",
["/"] = "/",
}
local range_repeat_unit = {
-- WP:UNIT wants unit repeated when a "multiply" range is used.
["x"] = true,
["×"] = true,
}
local function extract_item(index, numbers, arg)
-- Extract an item from arg and store the result in numbers[index].
-- If no argument or if argument is valid, return nil (no error);
-- otherwise, return an error message.
-- The stored result is:
-- * a table for a number (empty if there was no specified number); or
-- * a string for range text
-- Input like 1e3 is regarded as invalid for all except argument 1
-- which accepts e notation as an alternative to the 'e' argument.
-- Input group separators are removed.
local which = index
local function fail(msg)
local description
if which == 'e' then
description = mtext['mt-bad-exponent']
else
description = mtext['mt-parameter'] .. which
end
return description .. ' ' .. (msg or mtext['mt-not-number']) .. '.'
end
local result = {}
local range = range_types[arg]
if range then
if type(index) == 'number' and (index % 2 == 0) then
if index == 2 then
if numbers[1] and numbers[1].exp then
return fail(mtext['mt-cannot-range'])
end
numbers.has_ranges = true
else
if not numbers.has_ranges then
return fail(mtext['mt-need-range'])
end
end
numbers[index] = range
if range_repeat_unit[arg] then
-- Any "repeat" range forces unit (if any) to be repeated for all items.
numbers.isrepeat = true
end
return nil
end
return fail(mtext['mt-not-range'])
end
if numbers.has_ranges and type(index) == 'number' and (index % 2 == 0) then
return fail(mtext['mt-should-range'])
end
if index == 'e' then
local e = numbers[1] and numbers[1].exp
if e then
if arg then
return fail(mtext['mt-cannot-with-e'])
end
arg = e
which = 1
end
end
if arg and arg ~= '' then
arg = arg:gsub(numsep, '')
if numdot ~= '.' then
arg = arg:gsub(numdot, '.')
end
if arg:sub(1, 1) == '(' and arg:sub(-1) == ')' then
result.parens = true
arg = arg:sub(2, -2)
end
local a, b = arg:match('^(.+)[Ee](.+)$')
if a then
if index == 1 then
arg = a
result.exp = b
else
return fail(mtext['mt-cannot-e'])
end
end
local isnegative, propersign, prefix
local minus = '−'
prefix, arg = arg:match('^(.-)([%d.]+)$')
local value = tonumber(arg)
if not value then
return fail()
end
if arg:sub(1, 1) == '.' then
arg = '0' .. arg
end
if prefix == '' then
-- Ignore.
elseif prefix == '±' then
-- Display for first number, ignore for others.
if index == 1 then
propersign = '±'
end
elseif prefix == '+' then
propersign = '+'
elseif prefix == '-' or prefix == minus then
propersign = minus
isnegative = true
else
return fail()
end
result.clean = arg
result.sign = propersign or ''
result.value = isnegative and -value or value
end
numbers[index] = result
return nil -- no error
end
local function get_args(numbers, args)
-- Extract arguments and store the results in numbers.
-- Return nothing (no error) if ok; otherwise, return an error message.
for index = 1, 99 do
local which = index
local arg = args[which] -- has been trimmed
if not arg then
which = 'e'
arg = args[which]
end
local msg = extract_item(which, numbers, arg)
if msg then
return msg
end
if which == 'e' then
break
end
if index > 19 then
return mtext['mt-too-many-parameter']
end
end
if numbers.has_ranges and (#numbers % 2 == 0) then
return mtext['mt-need-number']
end
end
local function get_scale(text, ucode)
-- Return the value of text as a number, or throw an error.
-- This supports extremely basic expressions of the form:
-- a / b
-- a ^ b
-- where a and b are numbers or 'pi'.
local n = tonumber(text)
if n then
return n
end
n = text:gsub('pi', math.pi)
for _, op in ipairs({ '/', '^' }) do
local a, b = n:match('^(.-)' .. op .. '(.*)$')
if a then
a = tonumber(a)
b = tonumber(b)
if a and b then
if op == '/' then
return a / b
elseif op == '^' then
return a ^ b
end
end
break
end
end
error(string.format(mtext['mt-invalid-scale'], ucode, text))
end
local function get_builtin_unit(ucode, definitions)
-- Return table of information for the specified built-in unit, or nil if not known.
-- Each defined unit code must be followed by two spaces (not tab characters).
local _, pos = definitions:find('\n' .. ucode .. ' ', 1, true)
if pos then
local endline = definitions:find('%s*\n', pos)
if endline then
local result = {}
local n = 0
local text = definitions:sub(pos + 1, endline - 1):gsub('%s%s+', '\t')
for item in (text .. '\t'):gmatch('(%S.-)\t') do
if item == 'ALIAS' then
result.alias = true
elseif item == 'ANGLE' then
result.isangle = true
result.nospace = true
elseif item == 'NOSPACE' then
result.nospace = true
elseif item == 'SI' then
result.si = true
else
n = n + 1
if n == 1 then
local link, symbol = item:match('^%[%[([^|]+)|(.+)%]%]$')
if link then
result.symbol = symbol
result.link = link
n = 2
else
result.symbol = item
end
elseif n == 2 then
result.link = item
elseif n == 3 then
result.scale_text = item
result.scale = get_scale(item, ucode)
else
result.more_ignored = item
break
end
end
end
if result.si then
local s = result.symbol
if ucode == 'mc' .. s or ucode == 'mu' .. s then
result.ucode = 'µ' .. s -- unit code for convert should be this
end
end
if n >= 2 or (n >= 1 and result.alias) then
return result
end
-- Ignore invalid definition, treating it as a comment.
end
end
end
local function convert_lookup(ucode, value, scaled_top, want_link, si, options)
local lookup = require(convert_module)._unit
return lookup(ucode, {
value = value,
scaled_top = scaled_top,
link = want_link,
si = si,
sort = options.sortable,
})
end
local function get_unit(ucode, value, scaled_top, options)
local want_link = options.want_link
if scaled_top then
want_link = options.want_per_link
end
local data = mw.loadData(data_module)
local result = options.want_longscale and
get_builtin_unit(ucode, data.builtin_units_long_scale) or
get_builtin_unit(ucode, data.builtin_units)
local si, use_convert
if result then
if result.alias then
ucode = result.symbol
use_convert = true
end
if result.scale then
-- Setting si means convert will use the unit as given, and the sort key
-- will be calculated from the value without any extra scaling that may
-- occur if convert found the unit code. For example, if val defines the
-- unit 'year' with a scale and if si were not set, convert would also apply
-- its own scale because convert knows that a year is 31,557,600 seconds.
si = { result.symbol, result.link }
value = value * result.scale
end
if result.si then
ucode = result.ucode or ucode
si = { result.symbol, result.link }
use_convert = true
end
else
result = {}
use_convert = true
end
local convert_unit = convert_lookup(ucode, value, scaled_top, want_link, si, options)
result.sortkey = convert_unit.sortspan
if use_convert then
result.text = convert_unit.text
result.scaled_top = convert_unit.scaled_value
else
if want_link then
result.text = '[[' .. result.link .. '|' .. result.symbol .. ']]'
else
result.text = result.symbol
end
result.scaled_top = value
end
return result
end
local function makeunit(value, options)
-- Return table of information for the requested unit and options, or
-- return nil if no unit.
options = options or {}
local unit
local ucode = options.u
local percode = options.per
if ucode then
unit = get_unit(ucode, value, nil, options)
elseif percode then
unit = { nospace = true, scaled_top = value }
else
return nil
end
local text = unit.text or ''
local sortkey = unit.sortkey
if percode then
local function bracketed(code, text)
return code:find('[*./]') and '(' .. text .. ')' or text
end
local perunit = get_unit(percode, 1, unit.scaled_top, options)
text = (ucode and bracketed(ucode, text) or '') ..
'/' .. bracketed(percode, perunit.text)
sortkey = perunit.sortkey
end
if not (unit.nospace or options.nospace) then
text = ' ' .. text
end
return { text = text, isangle = unit.isangle, sortkey = sortkey }
end
local function list_units(mode)
-- Return wikitext to list the built-in units.
-- A unit code should not contain wikimarkup so don't bother escaping.
local data = mw.loadData(data_module)
local definitions = data.builtin_units .. data.builtin_units_long_scale
local last_was_blank = true
local n = 0
local result = {}
local function add(line)
if line == '' then
last_was_blank = true
else
if last_was_blank and n > 0 then
n = n + 1
result[n] = ''
end
last_was_blank = false
n = n + 1
result[n] = line
end
end
local si_prefixes = {
-- These are the prefixes recognized by convert; u is accepted for micro.
y = 'y',
z = 'z',
a = 'a',
f = 'f',
p = 'p',
n = 'n',
u = 'µ',
['µ'] = 'µ',
m = 'm',
c = 'c',
d = 'd',
da = 'da',
h = 'h',
k = 'k',
M = 'M',
G = 'G',
T = 'T',
P = 'P',
E = 'E',
Z = 'Z',
Y = 'Y',
}
local function is_valid(ucode, unit)
if unit and not unit.more_ignored then
assert(type(unit.symbol) == 'string' and unit.symbol ~= '')
if unit.alias then
if unit.link or unit.scale_text or unit.si then
return false
end
end
if unit.si then
if unit.scale_text then
return false
end
ucode = unit.ucode or ucode
local base = unit.symbol
if ucode == base then
unit.display = base
return true
end
local plen = #ucode - #base
if plen > 0 then
local prefix = si_prefixes[ucode:sub(1, plen)]
if prefix and ucode:sub(plen + 1) == base then
unit.display = prefix .. base
return true
end
end
else
unit.display = unit.symbol
return true
end
end
return false
end
local lookup = require(convert_module)._unit
local function show_convert(ucode, unit)
-- If a built-in unit defines a scale or sets the SI flag, any unit defined in
-- convert is not used (the scale or SI prefix's scale is used for a sort key).
-- If there is no scale or SI flag, and the unit is not defined in convert,
-- the sort key may not be correct; this allows such units to be identified.
if not (unit.si or unit.scale_text) then
if mode == 'convert' then
unit.show = not lookup(unit.alias and unit.symbol or ucode).unknown
unit.show_text = 'CONVERT'
elseif mode == 'unknown' then
unit.show = lookup(unit.alias and unit.symbol or ucode).unknown
unit.show_text = 'UNKNOWN'
elseif not unit.alias then
-- Show convert's scale in square brackets ('[1]' for an unknown unit).
-- Don't show scale for an alias because it's misleading for temperature
-- and an alias is probably not useful for anything else.
local scale = lookup(ucode, {value=1, sort='on'}).scaled_value
if type(scale) == 'number' then
scale = string.format('%.5g', scale):gsub('e%+?(%-?)0*(%d+)', 'e%1%2')
else
scale = '?'
end
unit.show = true
unit.show_text = '[' .. scale .. ']'
end
end
end
for line in definitions:gmatch('([^\n]*)\n') do
local pos, _ = line:find(' ', 1, true)
if pos then
local ucode = line:sub(1, pos - 1)
local unit = get_builtin_unit(ucode, '\n' .. line .. '\n')
if is_valid(ucode, unit) then
show_convert(ucode, unit)
local flags, text
if unit.alias then
text = unit.symbol
else
text = '[[' .. unit.link .. '|' .. unit.display .. ']]'
end
if unit.isangle then
unit.nospace = nil -- don't show redundant flag
end
for _, f in ipairs({
{ 'alias', 'ALIAS' },
{ 'isangle', 'ANGLE' },
{ 'nospace', 'NOSPACE' },
{ 'si', 'SI' },
{ 'scale_text', unit.scale_text },
{ 'show', unit.show_text },
}) do
if unit[f[1]] then
local t = f[2]
if t:match('^%u+$') then
t = '<small>' .. t .. '</small>'
end
if flags then
flags = flags .. ' ' .. t
else
flags = t
end
end
end
if flags then
text = text .. ' • ' .. flags
end
add(ucode .. ' = ' .. text .. '<br />')
else
add(line .. ' ◆ <b>invalid definition</b><br />')
end
else
add(line)
end
end
return table.concat(result, '\n')
end
local delimit_groups = require('Module:Gapnum').groups
local function delimit(sign, numstr, fmt)
-- Return sign and numstr (unsigned digits or numdot only) after formatting.
-- Four-digit integers are not formatted with gaps.
fmt = (fmt or ''):lower()
if fmt == 'none' or (fmt == '' and #numstr == 4 and numstr:match('^%d+$')) then
return sign .. numstr
end
-- Group number by integer and decimal parts.
-- If there is no decimal part, delimit_groups returns only one table.
local ipart, dpart = delimit_groups(numstr)
local result
if fmt == 'commas' then
result = sign .. table.concat(ipart, numsep)
if dpart then
result = result .. numdot .. table.concat(dpart)
end
else
-- Delimit with a small gap by default.
local groups = {}
groups[1] = table.remove(ipart, 1)
for _, v in ipairs(ipart) do
table.insert(groups, '<span style="margin-left:.25em;">' .. v .. '</span>')
end
if dpart then
table.insert(groups, numdot .. (table.remove(dpart, 1) or ''))
for _, v in ipairs(dpart) do
table.insert(groups, '<span style="margin-left:.25em;">' .. v .. '</span>')
end
end
result = sign .. table.concat(groups)
end
return result
end
local function sup_sub(sup, sub, align)
-- Return the same result as Module:Su except val defaults to align=right.
if align == 'l' or align == 'left' then
align = 'left'
elseif align == 'c' or align == 'center' then
align = 'center'
else
align = 'right'
end
return '<span style="display:inline-block;margin-bottom:-0.3em;vertical-align:-0.4em;line-height:1.2em;font-size:85%;text-align:' ..
align .. ';">' .. sup .. '<br />' .. sub .. '</span>'
end
local function range_text(items, unit_table, options)
local fmt = options.fmt
local nend = items.nend or ''
if items.isrepeat or unit_table.isangle then
nend = nend .. unit_table.text
end
local text = ''
for i = 1, #items do
if i % 2 == 0 then
text = text .. items[i]
else
text = text .. delimit(items[i].sign, items[i].clean, fmt) .. nend
end
end
return text
end
local function uncertainty_text(uncertainty, unit_table, options)
local angle, text, need_parens
if unit_table.isangle then
angle = unit_table.text
end
local upper = uncertainty.upper or {}
local lower = uncertainty.lower or {}
local uncU = upper.clean
if uncU then
local fmt = options.fmt
local uncL = lower.clean
if uncL then
uncU = delimit('+', uncU, fmt) .. (upper.errend or '')
uncL = delimit('−', uncL, fmt) .. (lower.errend or '')
if angle then
uncU = uncU .. angle
uncL = uncL .. angle
end
text = (angle or '') ..
'<span style="margin-left:0.3em;">' ..
sup_sub(uncU, uncL, options.align) ..
'</span>'
else
if upper.parens then
text = '(' .. uncU .. ')' -- old template did not delimit
else
text = (angle or '') ..
'<span style="margin-left:0.3em;margin-right:0.15em;">±</span>' ..
delimit('', uncU, fmt)
need_parens = true
end
if uncertainty.errend then
text = text .. uncertainty.errend
end
if angle then
text = text .. angle
end
end
else
if angle then
text = angle
end
end
return text, need_parens
end
local function _main(values, unit_spec, options)
if options.sandbox then
data_module = data_module .. '/sandbox'
convert_module = convert_module .. '/sandbox'
end
local action = options.action
if action then
if action == 'list' then
-- Kludge: am using the align parameter (a=xxx) for type of list.
return list_units(options.align)
end
return valerror('invalid action "' .. action .. '".', options.nocat)
end
local number = values.number or (values.numbers and values.numbers[1]) or {}
local e_10 = options.e or {}
local novalue = (number.value == nil and e_10.clean == nil)
local fmt = options.fmt
local want_sort = true
local sortable = options.sortable
if sortable == 'off' or (sortable == nil and novalue) then
want_sort = false
elseif sortable == 'debug' then
-- Same as sortable = 'on' but the sort key is displayed.
else
sortable = 'on'
end
local sort_value = 1
if want_sort then
sort_value = number.value or 1
if e_10.value and sort_value ~= 0 then
-- The 'if' avoids {{val|0|e=1234}} giving an invalid sort_value due to overflow.
sort_value = sort_value * 10^e_10.value
end
end
local unit_table = makeunit(sort_value, {
u = unit_spec.u,
want_link = unit_spec.want_link,
per = unit_spec.per,
want_per_link = unit_spec.want_per_link,
nospace = novalue,
want_longscale = unit_spec.want_longscale,
sortable = sortable,
})
local sortkey
if unit_table then
if want_sort then
sortkey = unit_table.sortkey
end
else
unit_table = { text = '' }
if want_sort then
sortkey = convert_lookup('dummy', sort_value, nil, nil, nil, { sortable = sortable }).sortspan
end
end
local final_unit = unit_table.isangle and '' or unit_table.text
local e_text, n_text, need_parens
local uncertainty = values.uncertainty
if uncertainty then
if number.clean then
n_text = delimit(number.sign, number.clean, fmt) .. (number.nend or '')
local text
text, need_parens = uncertainty_text(uncertainty, unit_table, options)
if text then
n_text = n_text .. text
end
else
n_text = ''
end
else
if values.numbers.isrepeat then
final_unit = ''
end
n_text = range_text(values.numbers, unit_table, options)
need_parens = true
end
if e_10.clean then
if need_parens then
n_text = '(' .. n_text .. ')'
end
e_text = '10<sup>' .. delimit(e_10.sign, e_10.clean, fmt) .. '</sup>'
if number.clean then
e_text = '<span style="margin-left:0.25em;margin-right:0.15em;">×</span>' .. e_text
end
else
e_text = ''
end
local result =
(sortkey or '') ..
(options.prefix or '') ..
n_text ..
e_text ..
final_unit ..
(options.suffix or '')
if result ~= '' then
result = '<span class="nowrap">' .. result .. '</span>'
end
return result .. (options.warning or '')
end
local function check_parameters(args, has_ranges, nocat)
-- Return warning text for the first problem parameter found, or nothing if ok.
local whitelist = {
a = true,
action = true,
debug = true,
e = true,
['end'] = true,
errend = true,
['+errend'] = true,
['-errend'] = true,
fmt = true,
['long scale'] = true,
long_scale = true,
longscale = true,
nocategory = true,
p = true,
s = true,
sortable = true,
u = true,
ul = true,
up = true,
upl = true,
}
for k, v in pairs(args) do
if type(k) == 'string' and not whitelist[k] then
local warning = string.format(mtext['mt-val-not-supported'], k, v)
return valerror(warning, nocat, true)
end
end
if not has_ranges and args[4] then
return valerror(mtext['mt-ignore-parameter4'], nocat, true)
end
end
local function main(frame)
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame, {wrappers = { 'Template:Val' }})
local nocat = args.nocategory
local numbers = {} -- table of number tables, perhaps with range text
local msg = get_args(numbers, args)
if msg then
return valerror(msg, nocat)
end
if args.u and args.ul then
return valerror(mtext['mt-both-u-ul'], nocat)
end
if args.up and args.upl then
return valerror(mtext['mt-both-up-upl'], nocat)
end
local values
if numbers.has_ranges then
-- Multiple values with range separators but no uncertainty.
numbers.nend = args['end']
values = {
numbers = numbers,
}
else
-- A single value with optional uncertainty.
local function setfield(i, dst, src)
local v = args[src]
if v then
if numbers[i] then
numbers[i][dst] = v
else
numbers[i] = { [dst] = v }
end
end
end
setfield(1, 'nend', 'end')
setfield(2, 'errend', '+errend')
setfield(3, 'errend', '-errend')
values = {
number = numbers[1],
uncertainty = {
upper = numbers[2],
lower = numbers[3],
errend = args.errend,
}
}
end
local unit_spec = {
u = args.ul or args.u,
want_link = args.ul ~= nil,
per = args.upl or args.up,
want_per_link = args.upl ~= nil,
want_longscale = (args.longscale or args.long_scale or args['long scale']) == 'on',
}
local options = {
action = args.action,
align = args.a,
e = numbers.e,
fmt = args.fmt,
nocat = nocat,
prefix = args.p,
sandbox = string.find(frame:getTitle(), 'sandbox', 1, true) ~= nil,
sortable = args.sortable or (args.debug == 'yes' and 'debug' or nil),
suffix = args.s,
warning = check_parameters(args, numbers.has_ranges, nocat),
}
return _main(values, unit_spec, options)
end
return { main = main, _main = _main }
899cf01cf6a449e10309108c9de56689e4205d5c
Module:Gapnum
828
44
104
103
2022-09-04T15:24:29Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local p = {}
local getArgs
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = 'Template:Gapnum'})
local n = args[1]
if not n then
error('Parameter 1 is required')
elseif not tonumber(n) and not tonumber(n, 36) then -- Validates any number with base ≤ 36
error('Unable to convert "' .. args[1] .. '" to a number')
end
local gap = args.gap
local precision = tonumber(args.prec)
return p.gaps(n,{gap=gap,prec=precision})
end
-- Not named p._main so that it has a better function name when required by Module:Val
function p.gaps(n,tbl)
local nstr = tostring(n)
if not tbl then
tbl = {}
end
local gap = tbl.gap or '.25em'
local int_part, frac_part = p.groups(n,tbl.prec)
local ret = mw.html.create('span')
:css('white-space','nowrap')
-- No gap necessary on first group
:wikitext(table.remove(int_part,1))
-- Build int part
for _, v in ipairs(int_part) do
ret:tag('span')
:css('margin-left',gap)
:wikitext(v)
end
if frac_part then
-- The first group after the decimal shouldn't have a gap
ret:wikitext('.' .. table.remove(frac_part,1))
-- Build frac part
for _, v in ipairs(frac_part) do
ret:tag('span')
:css('margin-left',gap)
:wikitext(v)
end
end
return ret
end
-- Creates tables where each element is a different group of the number
function p.groups(num,precision)
local nstr = tostring(num)
if not precision then
precision = -1
end
local decimalloc = nstr:find('.', 1, true)
local int_part, frac_part
if decimalloc == nil then
int_part = nstr
else
int_part = nstr:sub(1, decimalloc-1)
frac_part = nstr:sub(decimalloc + 1)
end
-- only define ret_i as an empty table, let ret_d stay nil
local ret_i,ret_d = {}
-- Loop to handle most of the groupings; from right to left, so that if a group has less than 3 members, it will be the first group
while int_part:len() > 3 do
-- Insert in first spot, since we're moving backwards
table.insert(ret_i,1,int_part:sub(-3))
int_part = int_part:sub(1,-4)
end
-- handle any left over numbers
if int_part:len() > 0 then
table.insert(ret_i,1,int_part)
end
if precision ~= 0 and frac_part then
ret_d = {}
if precision == -1 then
precision = frac_part:len()
end
-- Reduce the length of the string if required precision is less than actual precision
-- OR
-- Increase it (by adding 0s) if the required precision is more than actual
local offset = precision - frac_part:len()
if offset < 0 then
frac_part = frac_part:sub(1,precision)
elseif offset > 0 then
frac_part = frac_part .. string.rep('0', offset)
end
-- Allow groups of 3 or 2 (3 first)
for v in string.gmatch(frac_part,'%d%d%d?') do
table.insert(ret_d,v)
end
-- Preference for groups of 4 instead of groups of 1 at the end
if #frac_part % 3 == 1 then
if frac_part:len() == 1 then
ret_d = {frac_part}
else
local last_g = ret_d[#ret_d] or ''
last_g = last_g..frac_part:sub(-1)
ret_d[#ret_d] = last_g
end
end
end
return ret_i,ret_d
end
return p
b855346e2e3abc47591f883503c6108f922f0849
Module:Convert
828
46
108
107
2022-09-04T15:24:31Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- Convert a value from one unit of measurement to another.
-- Example: {{convert|123|lb|kg}} --> 123 pounds (56 kg)
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92)
local abs = math.abs
local floor = math.floor
local format = string.format
local log10 = math.log10
local ustring = mw.ustring
local ulen = ustring.len
local usub = ustring.sub
-- Configuration options to keep magic values in one location.
-- Conversion data and message text are defined in separate modules.
local config, maxsigfig
local numdot -- must be '.' or ',' or a character which works in a regex
local numsep, numsep_remove, numsep_remove2
local data_code, all_units
local text_code
local varname -- can be a code to use variable names that depend on value
local from_en_table -- to translate an output string of en digits to local language
local to_en_table -- to translate an input string of digits in local language to en
-- Use translation_table in convert/text to change the following.
local en_default -- true uses lang=en unless convert has lang=local or local digits
local group_method = 3 -- code for how many digits are in a group
local per_word = 'per' -- for units like "liters per kilometer"
local plural_suffix = 's' -- only other useful value is probably '' to disable plural unit names
local omitsep -- true to omit separator before local symbol/name
-- All units should be defined in the data module. However, to cater for quick changes
-- and experiments, any unknown unit is looked up in an extra data module, if it exists.
-- That module would be transcluded in only a small number of pages, so there should be
-- little server overhead from making changes, and changes should propagate quickly.
local extra_module -- name of module with extra units
local extra_units -- nil or table of extra units from extra_module
-- Some options in the invoking template can set variables used later in the module.
local currency_text -- for a user-defined currency symbol: {{convert|12|$/ha|$=€}} (euro replaces dollar)
local function from_en(text)
-- Input is a string representing a number in en digits with '.' decimal mark,
-- without digit grouping (which is done just after calling this).
-- Return the translation of the string with numdot and digits in local language.
if numdot ~= '.' then
text = text:gsub('%.', numdot)
end
if from_en_table then
text = text:gsub('%d', from_en_table)
end
return text
end
local function to_en(text)
-- Input is a string representing a number in the local language with
-- an optional numdot decimal mark and numsep digit grouping.
-- Return the translation of the string with '.' mark and en digits,
-- and no separators (they have to be removed here to handle cases like
-- numsep = '.' and numdot = ',' with input "1.234.567,8").
if to_en_table then
text = ustring.gsub(text, '%d', to_en_table)
end
if numsep_remove then
text = text:gsub(numsep_remove, '')
end
if numsep_remove2 then
text = text:gsub(numsep_remove2, '')
end
if numdot ~= '.' then
text = text:gsub(numdot, '.')
end
return text
end
local function decimal_mark(text)
-- Return ',' if text probably is using comma for decimal mark, or has no decimal mark.
-- Return '.' if text probably is using dot for decimal mark.
-- Otherwise return nothing (decimal mark not known).
if not text:find('[.,]') then return ',' end
text = text:gsub('^%-', ''):gsub('%+%d+/%d+$', ''):gsub('[Ee]%-?%d+$', '')
local decimal =
text:match('^0?([.,])%d+$') or
text:match('%d([.,])%d?%d?$') or
text:match('%d([.,])%d%d%d%d+$')
if decimal then return decimal end
if text:match('%.%d+%.') then return ',' end
if text:match('%,%d+,') then return '.' end
end
local add_warning, with_separator -- forward declarations
local function to_en_with_check(text, parms)
-- Version of to_en() for a wiki using numdot = ',' and numsep = '.' to check
-- text (an input number as a string) which might have been copied from enwiki.
-- For example, in '1.234' the '.' could be a decimal mark or a group separator.
-- From viwiki.
if to_en_table then
text = ustring.gsub(text, '%d', to_en_table)
end
if decimal_mark(text) == '.' then
local original = text
text = text:gsub(',', '') -- for example, interpret "1,234.5" as an enwiki value
if parms then
add_warning(parms, 0, 'cvt_enwiki_num', original, with_separator({}, text))
end
else
if numsep_remove then
text = text:gsub(numsep_remove, '')
end
if numsep_remove2 then
text = text:gsub(numsep_remove2, '')
end
if numdot ~= '.' then
text = text:gsub(numdot, '.')
end
end
return text
end
local function omit_separator(id)
-- Return true if there should be no separator before id (a unit symbol or name).
-- For zhwiki, there should be no separator if id uses local characters.
-- The following kludge should be a sufficient test.
if omitsep then
if id:sub(1, 2) == '-{' then -- for "-{...}-" content language variant
return true
end
if id:byte() > 127 then
local first = usub(id, 1, 1)
if first ~= 'Å' and first ~= '°' and first ~= 'µ' then
return true
end
end
end
return id:sub(1, 1) == '/' -- no separator before units like "/ha"
end
local spell_module -- name of module that can spell numbers
local speller -- function from that module to handle spelling (set if needed)
local wikidata_module, wikidata_data_module -- names of Wikidata modules
local wikidata_code, wikidata_data -- exported tables from those modules (set if needed)
local function set_config(args)
-- Set configuration options from template #invoke or defaults.
config = args
maxsigfig = config.maxsigfig or 14 -- maximum number of significant figures
local data_module, text_module
local sandbox = config.sandbox and ('/' .. config.sandbox) or ''
data_module = "Module:Convert/data" .. sandbox
text_module = "Module:Convert/text" .. sandbox
extra_module = "Module:Convert/extra" .. sandbox
wikidata_module = "Module:Convert/wikidata" .. sandbox
wikidata_data_module = "Module:Convert/wikidata/data" .. sandbox
spell_module = "Module:ConvertNumeric"
data_code = mw.loadData(data_module)
text_code = mw.loadData(text_module)
all_units = data_code.all_units
local translation = text_code.translation_table
if translation then
numdot = translation.numdot
numsep = translation.numsep
if numdot == ',' and numsep == '.' then
if text_code.all_messages.cvt_enwiki_num then
to_en = to_en_with_check
end
end
if translation.group then
group_method = translation.group
end
if translation.per_word then
per_word = translation.per_word
end
if translation.plural_suffix then
plural_suffix = translation.plural_suffix
end
varname = translation.varname
from_en_table = translation.from_en
local use_workaround = true
if use_workaround then
-- 2013-07-05 workaround bug by making a copy of the required table.
-- mw.ustring.gsub fails with a table (to_en_table) as the replacement,
-- if the table is accessed via mw.loadData.
local source = translation.to_en
if source then
to_en_table = {}
for k, v in pairs(source) do
to_en_table[k] = v
end
end
else
to_en_table = translation.to_en
end
if translation.lang == 'en default' then
en_default = true -- for hiwiki
end
omitsep = translation.omitsep -- for zhwiki
end
numdot = config.numdot or numdot or '.' -- decimal mark before fractional digits
numsep = config.numsep or numsep or ',' -- group separator for numbers
-- numsep should be ',' or '.' or '' or ' ' or a Unicode character.
-- numsep_remove must work in a regex to identify separators to be removed.
if numsep ~= '' then
numsep_remove = (numsep == '.') and '%.' or numsep
end
if numsep ~= ',' and numdot ~= ',' then
numsep_remove2 = ',' -- so numbers copied from enwiki will work
end
end
local function collection()
-- Return a table to hold items.
return {
n = 0,
add = function (self, item)
self.n = self.n + 1
self[self.n] = item
end,
}
end
local function divide(numerator, denominator)
-- Return integers quotient, remainder resulting from dividing the two
-- given numbers, which should be unsigned integers.
local quotient, remainder = floor(numerator / denominator), numerator % denominator
if not (0 <= remainder and remainder < denominator) then
-- Floating point limits may need this, as in {{convert|160.02|Ym|ydftin}}.
remainder = 0
end
return quotient, remainder
end
local function split(text, delimiter)
-- Return a numbered table with fields from splitting text.
-- The delimiter is used in a regex without escaping (for example, '.' would fail).
-- Each field has any leading/trailing whitespace removed.
local t = {}
text = text .. delimiter -- to get last item
for item in text:gmatch('%s*(.-)%s*' .. delimiter) do
table.insert(t, item)
end
return t
end
local function strip(text)
-- If text is a string, return its content with no leading/trailing
-- whitespace. Otherwise return nil (a nil argument gives a nil result).
if type(text) == 'string' then
return text:match("^%s*(.-)%s*$")
end
end
local function table_len(t)
-- Return length (<100) of a numbered table to replace #t which is
-- documented to not work if t is accessed via mw.loadData().
for i = 1, 100 do
if t[i] == nil then
return i - 1
end
end
end
local function wanted_category(catkey, catsort, want_warning)
-- Return message category if it is wanted in current namespace,
-- otherwise return ''.
local cat
local title = mw.title.getCurrentTitle()
if title then
local nsdefault = '0' -- default namespace: '0' = article; '0,10' = article and template
local namespace = title.namespace
for _, v in ipairs(split(config.nscat or nsdefault, ',')) do
if namespace == tonumber(v) then
cat = text_code.all_categories[want_warning and 'warning' or catkey]
if catsort and catsort ~= '' and cat:sub(-2) == ']]' then
cat = cat:sub(1, -3) .. '|' .. mw.text.nowiki(usub(catsort, 1, 20)) .. ']]'
end
break
end
end
end
return cat or ''
end
local function message(parms, mcode, is_warning)
-- Return wikitext for an error message, including category if specified
-- for the message type.
-- mcode = numbered table specifying the message:
-- mcode[1] = 'cvt_xxx' (string used as a key to get message info)
-- mcode[2] = 'parm1' (string to replace '$1' if any in message)
-- mcode[3] = 'parm2' (string to replace '$2' if any in message)
-- mcode[4] = 'parm3' (string to replace '$3' if any in message)
local msg
if type(mcode) == 'table' then
if mcode[1] == 'cvt_no_output' then
-- Some errors should cause convert to output an empty string,
-- for example, for an optional field in an infobox.
return ''
end
msg = text_code.all_messages[mcode[1]]
end
parms.have_problem = true
local function subparm(fmt, ...)
local rep = {}
for i, v in ipairs({...}) do
rep['$' .. i] = v
end
return (fmt:gsub('$%d+', rep))
end
if msg then
local parts = {}
local regex, replace = msg.regex, msg.replace
for i = 1, 3 do
local limit = 40
local s = mcode[i + 1]
if s then
if regex and replace then
s = s:gsub(regex, replace)
limit = nil -- allow long "should be" messages
end
-- Escape user input so it does not break the message.
-- To avoid tags (like {{convert|1<math>23</math>|m}}) breaking
-- the mouseover title, any strip marker starting with char(127) is
-- replaced with '...' (text not needing i18n).
local append
local pos = s:find(string.char(127), 1, true)
if pos then
append = '...'
s = s:sub(1, pos - 1)
end
if limit and ulen(s) > limit then
s = usub(s, 1, limit)
append = '...'
end
s = mw.text.nowiki(s) .. (append or '')
else
s = '?'
end
parts['$' .. i] = s
end
local function ispreview()
-- Return true if a prominent message should be shown.
if parms.test == 'preview' or parms.test == 'nopreview' then
-- For testing, can preview a real message or simulate a preview
-- when running automated tests.
return parms.test == 'preview'
end
local success, revid = pcall(function ()
return (parms.frame):preprocess('{{REVISIONID}}') end)
return success and (revid == '')
end
local want_warning = is_warning and
not config.warnings and -- show unobtrusive warnings if config.warnings not configured
not msg.nowarn -- but use msg settings, not standard warning, if specified
local title = string.gsub(msg[1] or 'Missing message', '$%d+', parts)
local text = want_warning and '*' or msg[2] or 'Missing message'
local cat = wanted_category(msg[3], mcode[2], want_warning)
local anchor = msg[4] or ''
local fmtkey = ispreview() and 'cvt_format_preview' or
(want_warning and 'cvt_format2' or msg.format or 'cvt_format')
local fmt = text_code.all_messages[fmtkey] or 'convert: bug'
return subparm(fmt, title:gsub('"', '"'), text, cat, anchor)
end
return 'Convert internal error: unknown message'
end
function add_warning(parms, level, key, text1, text2) -- for forward declaration above
-- If enabled, add a warning that will be displayed after the convert result.
-- A higher level is more verbose: more kinds of warnings are displayed.
-- To reduce output noise, only the first warning is displayed.
if level <= (tonumber(config.warnings) or 1) then
if parms.warnings == nil then
parms.warnings = message(parms, { key, text1, text2 }, true)
end
end
end
local function spell_number(parms, inout, number, numerator, denominator)
-- Return result of spelling (number, numerator, denominator), or
-- return nil if spelling is not available or not supported for given text.
-- Examples (each value must be a string or nil):
-- number numerator denominator output
-- ------ --------- ----------- -------------------
-- "1.23" nil nil one point two three
-- "1" "2" "3" one and two thirds
-- nil "2" "3" two thirds
if not speller then
local function get_speller(module)
return require(module).spell_number
end
local success
success, speller = pcall(get_speller, spell_module)
if not success or type(speller) ~= 'function' then
add_warning(parms, 1, 'cvt_no_spell', 'spell')
return nil
end
end
local case
if parms.spell_upper == inout then
case = true
parms.spell_upper = nil -- only uppercase first word in a multiple unit
end
local sp = not parms.opt_sp_us
local adj = parms.opt_adjectival
return speller(number, numerator, denominator, case, sp, adj)
end
------------------------------------------------------------------------
-- BEGIN: Code required only for built-in units.
-- LATER: If need much more code, move to another module to simplify this module.
local function speed_of_sound(altitude)
-- This is for the Mach built-in unit of speed.
-- Return speed of sound in metres per second at given altitude in feet.
-- If no altitude given, use default (zero altitude = sea level).
-- Table gives speed of sound in miles per hour at various altitudes:
-- altitude = -17,499 to 402,499 feet
-- mach_table[a + 4] = s where
-- a = (altitude / 5000) rounded to nearest integer (-3 to 80)
-- s = speed of sound (mph) at that altitude
-- LATER: Should calculate result from an interpolation between the next
-- lower and higher altitudes in table, rather than rounding to nearest.
-- From: http://www.aerospaceweb.org/question/atmosphere/q0112.shtml
local mach_table = { -- a =
799.5, 787.0, 774.2, 761.207051, -- -3 to 0
748.0, 734.6, 721.0, 707.0, 692.8, 678.3, 663.5, 660.1, 660.1, 660.1, -- 1 to 10
660.1, 660.1, 660.1, 662.0, 664.3, 666.5, 668.9, 671.1, 673.4, 675.6, -- 11 to 20
677.9, 683.7, 689.9, 696.0, 702.1, 708.1, 714.0, 719.9, 725.8, 731.6, -- 21 to 30
737.3, 737.7, 737.7, 736.2, 730.5, 724.6, 718.8, 712.9, 707.0, 701.0, -- 31 to 40
695.0, 688.9, 682.8, 676.6, 670.4, 664.1, 657.8, 652.9, 648.3, 643.7, -- 41 to 50
639.1, 634.4, 629.6, 624.8, 620.0, 615.2, 613.2, 613.2, 613.2, 613.5, -- 51 to 60
614.4, 615.3, 616.7, 619.8, 623.4, 629.7, 635.0, 641.1, 650.6, 660.0, -- 61 to 70
672.5, 674.3, 676.1, 677.9, 679.7, 681.5, 683.3, 685.1, 686.8, 688.6, -- 71 to 80
}
altitude = altitude or 0
local a = (altitude < 0) and -altitude or altitude
a = floor(a / 5000 + 0.5)
if altitude < 0 then
a = -a
end
if a < -3 then
a = -3
elseif a > 80 then
a = 80
end
return mach_table[a + 4] * 0.44704 -- mph converted to m/s
end
-- END: Code required only for built-in units.
------------------------------------------------------------------------
local function add_style(parms, class)
-- Add selected template style to parms if not already present.
parms.templatestyles = parms.templatestyles or {}
if not parms.templatestyles[class] then
parms.templatestyles[class] = parms.frame:extensionTag({
name = 'templatestyles', args = { src = text_code.titles[class] }
})
end
end
local function get_styles(parms)
-- Return string of required template styles, empty if none.
if parms.templatestyles then
local t = {}
for _, v in pairs(parms.templatestyles) do
table.insert(t, v)
end
return table.concat(t)
end
return ''
end
local function get_range(word)
-- Return a range (string or table) corresponding to word (like "to"),
-- or return nil if not a range word.
local ranges = text_code.ranges
return ranges.types[word] or ranges.types[ranges.aliases[word]]
end
local function check_mismatch(unit1, unit2)
-- If unit1 cannot be converted to unit2, return an error message table.
-- This allows conversion between units of the same type, and between
-- Nm (normally torque) and ftlb (energy), as in gun-related articles.
-- This works because Nm is the base unit (scale = 1) for both the
-- primary type (torque), and the alternate type (energy, where Nm = J).
-- A match occurs if the primary types are the same, or if unit1 matches
-- the alternate type of unit2, and vice versa. That provides a whitelist
-- of which conversions are permitted between normally incompatible types.
if unit1.utype == unit2.utype or
(unit1.utype == unit2.alttype and unit1.alttype == unit2.utype) then
return nil
end
return { 'cvt_mismatch', unit1.utype, unit2.utype }
end
local function override_from(out_table, in_table, fields)
-- Copy the specified fields from in_table to out_table, but do not
-- copy nil fields (keep any corresponding field in out_table).
for _, field in ipairs(fields) do
if in_table[field] then
out_table[field] = in_table[field]
end
end
end
local function shallow_copy(t)
-- Return a shallow copy of table t.
-- Do not need the features and overhead of the Scribunto mw.clone().
local result = {}
for k, v in pairs(t) do
result[k] = v
end
return result
end
local unit_mt = {
-- Metatable to get missing values for a unit that does not accept SI prefixes.
-- Warning: The boolean value 'false' is returned for any missing field
-- so __index is not called twice for the same field in a given unit.
__index = function (self, key)
local value
if key == 'name1' or key == 'sym_us' then
value = self.symbol
elseif key == 'name2' then
value = self.name1 .. plural_suffix
elseif key == 'name1_us' then
value = self.name1
if not rawget(self, 'name2_us') then
-- If name1_us is 'foot', do not make name2_us by appending plural_suffix.
self.name2_us = self.name2
end
elseif key == 'name2_us' then
local raw1_us = rawget(self, 'name1_us')
if raw1_us then
value = raw1_us .. plural_suffix
else
value = self.name2
end
elseif key == 'link' then
value = self.name1
else
value = false
end
rawset(self, key, value)
return value
end
}
local function prefixed_name(unit, name, index)
-- Return unit name with SI prefix inserted at correct position.
-- index = 1 (name1), 2 (name2), 3 (name1_us), 4 (name2_us).
-- The position is a byte (not character) index, so use Lua's sub().
local pos = rawget(unit, 'prefix_position')
if type(pos) == 'string' then
pos = tonumber(split(pos, ',')[index])
end
if pos then
return name:sub(1, pos - 1) .. unit.si_name .. name:sub(pos)
end
return unit.si_name .. name
end
local unit_prefixed_mt = {
-- Metatable to get missing values for a unit that accepts SI prefixes.
-- Before use, fields si_name, si_prefix must be defined.
-- The unit must define _symbol, _name1 and
-- may define _sym_us, _name1_us, _name2_us
-- (_sym_us, _name2_us may be defined for a language using sp=us
-- to refer to a variant unrelated to U.S. units).
__index = function (self, key)
local value
if key == 'symbol' then
value = self.si_prefix .. self._symbol
elseif key == 'sym_us' then
value = rawget(self, '_sym_us')
if value then
value = self.si_prefix .. value
else
value = self.symbol
end
elseif key == 'name1' then
value = prefixed_name(self, self._name1, 1)
elseif key == 'name2' then
value = rawget(self, '_name2')
if value then
value = prefixed_name(self, value, 2)
else
value = self.name1 .. plural_suffix
end
elseif key == 'name1_us' then
value = rawget(self, '_name1_us')
if value then
value = prefixed_name(self, value, 3)
else
value = self.name1
end
elseif key == 'name2_us' then
value = rawget(self, '_name2_us')
if value then
value = prefixed_name(self, value, 4)
elseif rawget(self, '_name1_us') then
value = self.name1_us .. plural_suffix
else
value = self.name2
end
elseif key == 'link' then
value = self.name1
else
value = false
end
rawset(self, key, value)
return value
end
}
local unit_per_mt = {
-- Metatable to get values for a per unit of form "x/y".
-- This is never called to determine a unit name or link because per units
-- are handled as a special case.
-- Similarly, the default output is handled elsewhere, and for a symbol
-- this is only called from get_default() for default_exceptions.
__index = function (self, key)
local value
if key == 'symbol' then
local per = self.per
local unit1, unit2 = per[1], per[2]
if unit1 then
value = unit1[key] .. '/' .. unit2[key]
else
value = '/' .. unit2[key]
end
elseif key == 'sym_us' then
value = self.symbol
elseif key == 'scale' then
local per = self.per
local unit1, unit2 = per[1], per[2]
value = (unit1 and unit1.scale or 1) * self.scalemultiplier / unit2.scale
else
value = false
end
rawset(self, key, value)
return value
end
}
local function make_per(unitcode, unit_table, ulookup)
-- Return true, t where t is a per unit with unit codes expanded to unit tables,
-- or return false, t where t is an error message table.
local result = {
unitcode = unitcode,
utype = unit_table.utype,
per = {}
}
override_from(result, unit_table, { 'invert', 'iscomplex', 'default', 'link', 'symbol', 'symlink' })
result.symbol_raw = (result.symbol or false) -- to distinguish between a defined exception and a metatable calculation
local prefix
for i, v in ipairs(unit_table.per) do
if i == 1 and v == '' then
-- First unit symbol can be empty; that gives a nil first unit table.
elseif i == 1 and text_code.currency[v] then
prefix = currency_text or v
else
local success, t = ulookup(v)
if not success then return false, t end
result.per[i] = t
end
end
local multiplier = unit_table.multiplier
if not result.utype then
-- Creating an automatic per unit.
local unit1 = result.per[1]
local utype = (unit1 and unit1.utype or prefix or '') .. '/' .. result.per[2].utype
local t = data_code.per_unit_fixups[utype]
if t then
if type(t) == 'table' then
utype = t.utype or utype
result.link = result.link or t.link
multiplier = multiplier or t.multiplier
else
utype = t
end
end
result.utype = utype
end
result.scalemultiplier = multiplier or 1
result.vprefix = prefix or false -- set to non-nil to avoid calling __index
return true, setmetatable(result, unit_per_mt)
end
local function lookup(parms, unitcode, what, utable, fails, depth)
-- Return true, t where t is a copy of the unit's converter table,
-- or return false, t where t is an error message table.
-- Parameter 'what' determines whether combination units are accepted:
-- 'no_combination' : single unit only
-- 'any_combination' : single unit or combination or output multiple
-- 'only_multiple' : single unit or output multiple only
-- Parameter unitcode is a symbol (like 'g'), with an optional SI prefix (like 'kg').
-- If, for example, 'kg' is in this table, that entry is used;
-- otherwise the prefix ('k') is applied to the base unit ('g').
-- If unitcode is a known combination code (and if allowed by what),
-- a table of output multiple unit tables is included in the result.
-- For compatibility with the old template, an underscore in a unitcode is
-- replaced with a space so usage like {{convert|350|board_feet}} works.
-- Wikignomes may also put two spaces or " " in combinations, so
-- replace underscore, " ", and multiple spaces with a single space.
utable = utable or parms.unittable or all_units
fails = fails or {}
depth = depth and depth + 1 or 1
if depth > 9 then
-- There are ways to mistakenly define units which result in infinite
-- recursion when lookup() is called. That gives a long delay and very
-- confusing error messages, so the depth parameter is used as a guard.
return false, { 'cvt_lookup', unitcode }
end
if unitcode == nil or unitcode == '' then
return false, { 'cvt_no_unit' }
end
unitcode = unitcode:gsub('_', ' '):gsub(' ', ' '):gsub(' +', ' ')
local function call_make_per(t)
return make_per(unitcode, t,
function (ucode) return lookup(parms, ucode, 'no_combination', utable, fails, depth) end
)
end
local t = utable[unitcode]
if t then
if t.shouldbe then
return false, { 'cvt_should_be', t.shouldbe }
end
if t.sp_us then
parms.opt_sp_us = true
end
local target = t.target -- nil, or unitcode is an alias for this target
if target then
local success, result = lookup(parms, target, what, utable, fails, depth)
if not success then return false, result end
override_from(result, t, { 'customary', 'default', 'link', 'symbol', 'symlink' })
local multiplier = t.multiplier
if multiplier then
result.multiplier = tostring(multiplier)
result.scale = result.scale * multiplier
end
return true, result
end
if t.per then
return call_make_per(t)
end
local combo = t.combination -- nil or a table of unitcodes
if combo then
local multiple = t.multiple
if what == 'no_combination' or (what == 'only_multiple' and not multiple) then
return false, { 'cvt_bad_unit', unitcode }
end
-- Recursively create a combination table containing the
-- converter table of each unitcode.
local result = { utype = t.utype, multiple = multiple, combination = {} }
local cvt = result.combination
for i, v in ipairs(combo) do
local success, t = lookup(parms, v, multiple and 'no_combination' or 'only_multiple', utable, fails, depth)
if not success then return false, t end
cvt[i] = t
end
return true, result
end
local result = shallow_copy(t)
result.unitcode = unitcode
if result.prefixes then
result.si_name = ''
result.si_prefix = ''
return true, setmetatable(result, unit_prefixed_mt)
end
return true, setmetatable(result, unit_mt)
end
local SIprefixes = text_code.SIprefixes
for plen = SIprefixes[1] or 2, 1, -1 do
-- Look for an SI prefix; should never occur with an alias.
-- Check for longer prefix first ('dam' is decametre).
-- SIprefixes[1] = prefix maximum #characters (as seen by mw.ustring.sub).
local prefix = usub(unitcode, 1, plen)
local si = SIprefixes[prefix]
if si then
local t = utable[usub(unitcode, plen+1)]
if t and t.prefixes then
local result = shallow_copy(t)
result.unitcode = unitcode
result.si_name = parms.opt_sp_us and si.name_us or si.name
result.si_prefix = si.prefix or prefix
result.scale = t.scale * 10 ^ (si.exponent * t.prefixes)
return true, setmetatable(result, unit_prefixed_mt)
end
end
end
-- Accept user-defined combinations like "acre+m2+ha" or "acre m2 ha" for output.
-- If '+' is used, each unit code can include a space, and any error is fatal.
-- If ' ' is used and if each space-separated word is a unit code, it is a combo,
-- but errors are not fatal so the unit code can be looked up as an extra unit.
local err_is_fatal
local combo = collection()
if unitcode:find('+', 1, true) then
err_is_fatal = true
for item in (unitcode .. '+'):gmatch('%s*(.-)%s*%+') do
if item ~= '' then
combo:add(item)
end
end
elseif unitcode:find('%s') then
for item in unitcode:gmatch('%S+') do
combo:add(item)
end
end
if combo.n > 1 then
local function lookup_combo()
if what == 'no_combination' or what == 'only_multiple' then
return false, { 'cvt_bad_unit', unitcode }
end
local result = { combination = {} }
local cvt = result.combination
for i, v in ipairs(combo) do
local success, t = lookup(parms, v, 'only_multiple', utable, fails, depth)
if not success then return false, t end
if i == 1 then
result.utype = t.utype
else
local mismatch = check_mismatch(result, t)
if mismatch then
return false, mismatch
end
end
cvt[i] = t
end
return true, result
end
local success, result = lookup_combo()
if success or err_is_fatal then
return success, result
end
end
-- Accept any unit with an engineering notation prefix like "e6cuft"
-- (million cubic feet), but not chained prefixes like "e3e6cuft",
-- and not if the unit is a combination or multiple,
-- and not if the unit has an offset or is a built-in.
-- Only en digits are accepted.
local exponent, baseunit = unitcode:match('^e(%d+)(.*)')
if exponent then
local engscale = text_code.eng_scales[exponent]
if engscale then
local success, result = lookup(parms, baseunit, 'no_combination', utable, fails, depth)
if success and not (result.offset or result.builtin or result.engscale) then
result.unitcode = unitcode -- 'e6cuft' not 'cuft'
result.defkey = unitcode -- key to lookup default exception
result.engscale = engscale
result.scale = result.scale * 10 ^ tonumber(exponent)
return true, result
end
end
end
-- Look for x/y; split on right-most slash to get scale correct (x/y/z is x/y per z).
local top, bottom = unitcode:match('^(.-)/([^/]+)$')
if top and not unitcode:find('e%d') then
-- If valid, create an automatic per unit for an "x/y" unit code.
-- The unitcode must not include extraneous spaces.
-- Engineering notation (apart from at start and which has been stripped before here),
-- is not supported so do not make a per unit if find text like 'e3' in unitcode.
local success, result = call_make_per({ per = {top, bottom} })
if success then
return true, result
end
end
if not parms.opt_ignore_error and not get_range(unitcode) then
-- Want the "what links here" list for the extra_module to show only cases
-- where an extra unit is used, so do not require it if invoked from {{val}}
-- or if looking up a range word which cannot be a unit.
if not extra_units then
local success, extra = pcall(function () return require(extra_module).extra_units end)
if success and type(extra) == 'table' then
extra_units = extra
end
end
if extra_units then
-- A unit in one data table might refer to a unit in the other table, so
-- switch between them, relying on fails or depth to terminate loops.
if not fails[unitcode] then
fails[unitcode] = true
local other = (utable == all_units) and extra_units or all_units
local success, result = lookup(parms, unitcode, what, other, fails, depth)
if success then
return true, result
end
end
end
end
if to_en_table then
-- At fawiki it is common to translate all digits so a unit like "km2" becomes "km۲".
local en_code = ustring.gsub(unitcode, '%d', to_en_table)
if en_code ~= unitcode then
return lookup(parms, en_code, what, utable, fails, depth)
end
end
return false, { 'cvt_unknown', unitcode }
end
local function valid_number(num)
-- Return true if num is a valid number.
-- In Scribunto (different from some standard Lua), when expressed as a string,
-- overflow or other problems are indicated with text like "inf" or "nan"
-- which are regarded as invalid here (each contains "n").
if type(num) == 'number' and tostring(num):find('n', 1, true) == nil then
return true
end
end
local function hyphenated(name, parts)
-- Return a hyphenated form of given name (for adjectival usage).
-- The name may be linked and the target of the link must not be changed.
-- Hypothetical examples:
-- [[long ton|ton]] → [[long ton|ton]] (no change)
-- [[tonne|long ton]] → [[tonne|long-ton]]
-- [[metric ton|long ton]] → [[metric ton|long-ton]]
-- [[long ton]] → [[long ton|long-ton]]
-- Input can also have multiple links in a single name like:
-- [[United States customary units|U.S.]] [[US gallon|gallon]]
-- [[mile]]s per [[United States customary units|U.S.]] [[quart]]
-- [[long ton]]s per [[short ton]]
-- Assume that links cannot be nested (never like "[[abc[[def]]ghi]]").
-- This uses a simple and efficient procedure that works for most cases.
-- Some units (if used) would require more, and can later think about
-- adding a method to handle exceptions.
-- The procedure is to replace each space with a hyphen, but
-- not a space after ')' [for "(pre-1954 US) nautical mile"], and
-- not spaces immediately before '(' or in '(...)' [for cases like
-- "British thermal unit (ISO)" and "Calorie (International Steam Table)"].
if name:find(' ', 1, true) then
if parts then
local pos
if name:sub(1, 1) == '(' then
pos = name:find(')', 1, true)
if pos then
return name:sub(1, pos+1) .. name:sub(pos+2):gsub(' ', '-')
end
elseif name:sub(-1) == ')' then
pos = name:find('(', 1, true)
if pos then
return name:sub(1, pos-2):gsub(' ', '-') .. name:sub(pos-1)
end
end
return name:gsub(' ', '-')
end
parts = collection()
for before, item, after in name:gmatch('([^[]*)(%[%[[^[]*%]%])([^[]*)') do
if item:find(' ', 1, true) then
local prefix
local plen = item:find('|', 1, true)
if plen then
prefix = item:sub(1, plen)
item = item:sub(plen + 1, -3)
else
prefix = item:sub(1, -3) .. '|'
item = item:sub(3, -3)
end
item = prefix .. hyphenated(item, parts) .. ']]'
end
parts:add(before:gsub(' ', '-') .. item .. after:gsub(' ', '-'))
end
if parts.n == 0 then
-- No link like "[[...]]" was found in the original name.
parts:add(hyphenated(name, parts))
end
return table.concat(parts)
end
return name
end
local function hyphenated_maybe(parms, want_name, sep, id, inout)
-- Return s, f where
-- s = id, possibly modified
-- f = true if hyphenated
-- Possible modifications: hyphenate; prepend '-'; append mid text.
if id == nil or id == '' then
return ''
end
local mid = (inout == (parms.opt_flip and 'out' or 'in')) and parms.mid or ''
if want_name then
if parms.opt_adjectival then
return '-' .. hyphenated(id) .. mid, true
end
if parms.opt_add_s and id:sub(-1) ~= 's' then
id = id .. 's' -- for nowiki
end
end
return sep .. id .. mid
end
local function use_minus(text)
-- Return text with Unicode minus instead of '-', if present.
if text:sub(1, 1) == '-' then
return MINUS .. text:sub(2)
end
return text
end
local function digit_groups(parms, text, method)
-- Return a numbered table of groups of digits (left-to-right, in local language).
-- Parameter method is a number or nil:
-- 3 for 3-digit grouping (default), or
-- 2 for 3-then-2 grouping (only for digits before decimal mark).
local len_right
local len_left = text:find('.', 1, true)
if len_left then
len_right = #text - len_left
len_left = len_left - 1
else
len_left = #text
end
local twos = method == 2 and len_left > 5
local groups = collection()
local run = len_left
local n
if run < 4 or (run == 4 and parms.opt_comma5) then
if parms.opt_gaps then
n = run
else
n = #text
end
elseif twos then
n = run % 2 == 0 and 1 or 2
else
n = run % 3 == 0 and 3 or run % 3
end
while run > 0 do
groups:add(n)
run = run - n
n = (twos and run > 3) and 2 or 3
end
if len_right then
if groups.n == 0 then
groups:add(0)
end
if parms.opt_gaps and len_right > 3 then
local want4 = not parms.opt_gaps3 -- true gives no gap before trailing single digit
local isfirst = true
run = len_right
while run > 0 do
n = (want4 and run == 4) and 4 or (run > 3 and 3 or run)
if isfirst then
isfirst = false
groups[groups.n] = groups[groups.n] + 1 + n
else
groups:add(n)
end
run = run - n
end
else
groups[groups.n] = groups[groups.n] + 1 + len_right
end
end
local pos = 1
for i, length in ipairs(groups) do
groups[i] = from_en(text:sub(pos, pos + length - 1))
pos = pos + length
end
return groups
end
function with_separator(parms, text) -- for forward declaration above
-- Input text is a number in en digits with optional '.' decimal mark.
-- Return an equivalent, formatted for display:
-- with a custom decimal mark instead of '.', if wanted
-- with thousand separators inserted, if wanted
-- digits in local language
-- The given text is like '123' or '123.' or '12345.6789'.
-- The text has no sign (caller inserts that later, if necessary).
-- When using gaps, they are inserted before and after the decimal mark.
-- Separators are inserted only before the decimal mark.
-- A trailing dot (as in '123.') is removed because their use appears to
-- be accidental, and such a number should be shown as '123' or '123.0'.
-- It is useful for convert to suppress the dot so, for example, '4000.'
-- is a simple way of indicating that all the digits are significant.
if text:sub(-1) == '.' then
text = text:sub(1, -2)
end
if #text < 4 or parms.opt_nocomma or numsep == '' then
return from_en(text)
end
local groups = digit_groups(parms, text, group_method)
if parms.opt_gaps then
if groups.n <= 1 then
return groups[1] or ''
end
local nowrap = '<span style="white-space: nowrap">'
local gap = '<span style="margin-left: 0.25em">'
local close = '</span>'
return nowrap .. groups[1] .. gap .. table.concat(groups, close .. gap, 2, groups.n) .. close .. close
end
return table.concat(groups, numsep)
end
-- An input value like 1.23e12 is displayed using scientific notation (1.23×10¹²).
-- That also makes the output use scientific notation, except for small values.
-- In addition, very small or very large output values use scientific notation.
-- Use format(fmtpower, significand, '10', exponent) where each argument is a string.
local fmtpower = '%s<span style="margin:0 .15em 0 .25em">×</span>%s<sup>%s</sup>'
local function with_exponent(parms, show, exponent)
-- Return wikitext to display the implied value in scientific notation.
-- Input uses en digits; output uses digits in local language.
return format(fmtpower, with_separator(parms, show), from_en('10'), use_minus(from_en(tostring(exponent))))
end
local function make_sigfig(value, sigfig)
-- Return show, exponent that are equivalent to the result of
-- converting the number 'value' (where value >= 0) to a string,
-- rounded to 'sigfig' significant figures.
-- The returned items are:
-- show: a string of digits; no sign and no dot;
-- there is an implied dot before show.
-- exponent: a number (an integer) to shift the implied dot.
-- Resulting value = tonumber('.' .. show) * 10^exponent.
-- Examples:
-- make_sigfig(23.456, 3) returns '235', 2 (.235 * 10^2).
-- make_sigfig(0.0023456, 3) returns '235', -2 (.235 * 10^-2).
-- make_sigfig(0, 3) returns '000', 1 (.000 * 10^1).
if sigfig <= 0 then
sigfig = 1
elseif sigfig > maxsigfig then
sigfig = maxsigfig
end
if value == 0 then
return string.rep('0', sigfig), 1
end
local exp, fracpart = math.modf(log10(value))
if fracpart >= 0 then
fracpart = fracpart - 1
exp = exp + 1
end
local digits = format('%.0f', 10^(fracpart + sigfig))
if #digits > sigfig then
-- Overflow (for sigfig=3: like 0.9999 rounding to "1000"; need "100").
digits = digits:sub(1, sigfig)
exp = exp + 1
end
assert(#digits == sigfig, 'Bug: rounded number has wrong length')
return digits, exp
end
-- Fraction output format.
local fracfmt = {
{ -- Like {{frac}} (fraction slash).
'<span class="frac" role="math">{SIGN}<span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1/2
'<span class="frac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1+2/3
style = 'frac',
},
{ -- Like {{sfrac}} (stacked fraction, that is, horizontal bar).
'<span class="sfrac tion" role="math">{SIGN}<span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span>', -- 1//2
'<span class="sfrac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="tion"><span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span></span>', -- 1+2//3
style = 'sfrac',
},
}
local function format_fraction(parms, inout, negative, wholestr, numstr, denstr, do_spell, style)
-- Return wikitext for a fraction, possibly spelled.
-- Inputs use en digits and have no sign; output uses digits in local language.
local wikitext
if not style then
style = parms.opt_fraction_horizontal and 2 or 1
end
if wholestr == '' then
wholestr = nil
end
local substitute = {
SIGN = negative and MINUS or '',
WHOLE = wholestr and with_separator(parms, wholestr),
NUM = from_en(numstr),
DEN = from_en(denstr),
}
wikitext = fracfmt[style][wholestr and 2 or 1]:gsub('{(%u+)}', substitute)
if do_spell then
if negative then
if wholestr then
wholestr = '-' .. wholestr
else
numstr = '-' .. numstr
end
end
local s = spell_number(parms, inout, wholestr, numstr, denstr)
if s then
return s
end
end
add_style(parms, fracfmt[style].style)
return wikitext
end
local function format_number(parms, show, exponent, isnegative)
-- Parameter show is a string or a table containing strings.
-- Each string is a formatted number in en digits and optional '.' decimal mark.
-- A table represents a fraction: integer, numerator, denominator;
-- if a table is given, exponent must be nil.
-- Return t where t is a table with fields:
-- show = wikitext formatted to display implied value
-- (digits in local language)
-- is_scientific = true if show uses scientific notation
-- clean = unformatted show (possibly adjusted and with inserted '.')
-- (en digits)
-- sign = '' or MINUS
-- exponent = exponent (possibly adjusted)
-- The clean and exponent fields can be used to calculate the
-- rounded absolute value, if needed.
--
-- The value implied by the arguments is found from:
-- exponent is nil; and
-- show is a string of digits (no sign), with an optional dot;
-- show = '123.4' is value 123.4, '1234' is value 1234.0;
-- or:
-- exponent is an integer indicating where dot should be;
-- show is a string of digits (no sign and no dot);
-- there is an implied dot before show;
-- show does not start with '0';
-- show = '1234', exponent = 3 is value 0.1234*10^3 = 123.4.
--
-- The formatted result:
-- * Is for an output value and is spelled if wanted and possible.
-- * Includes a Unicode minus if isnegative and not spelled.
-- * Uses a custom decimal mark, if wanted.
-- * Has digits grouped where necessary, if wanted.
-- * Uses scientific notation if requested, or for very small or large values
-- (which forces result to not be spelled).
-- * Has no more than maxsigfig significant digits
-- (same as old template and {{#expr}}).
local xhi, xlo -- these control when scientific notation (exponent) is used
if parms.opt_scientific then
xhi, xlo = 4, 2 -- default for output if input uses e-notation
elseif parms.opt_scientific_always then
xhi, xlo = 0, 0 -- always use scientific notation (experimental)
else
xhi, xlo = 10, 4 -- default
end
local sign = isnegative and MINUS or ''
local maxlen = maxsigfig
local tfrac
if type(show) == 'table' then
tfrac = show
show = tfrac.wholestr
assert(exponent == nil, 'Bug: exponent given with fraction')
end
if not tfrac and not exponent then
local integer, dot, decimals = show:match('^(%d*)(%.?)(.*)')
if integer == '0' or integer == '' then
local zeros, figs = decimals:match('^(0*)([^0]?.*)')
if #figs == 0 then
if #zeros > maxlen then
show = '0.' .. zeros:sub(1, maxlen)
end
elseif #zeros >= xlo then
show = figs
exponent = -#zeros
elseif #figs > maxlen then
show = '0.' .. zeros .. figs:sub(1, maxlen)
end
elseif #integer >= xhi then
show = integer .. decimals
exponent = #integer
else
maxlen = maxlen + #dot
if #show > maxlen then
show = show:sub(1, maxlen)
end
end
end
if exponent then
local function zeros(n)
return string.rep('0', n)
end
if #show > maxlen then
show = show:sub(1, maxlen)
end
if exponent > xhi or exponent <= -xlo or (exponent == xhi and show ~= '1' .. zeros(xhi - 1)) then
-- When xhi, xlo = 10, 4 (the default), scientific notation is used if the
-- rounded value satisfies: value >= 1e9 or value < 1e-4 (1e9 = 0.1e10),
-- except if show is '1000000000' (1e9), for example:
-- {{convert|1000000000|m|m|sigfig=10}} → 1,000,000,000 metres (1,000,000,000 m)
local significand
if #show > 1 then
significand = show:sub(1, 1) .. '.' .. show:sub(2)
else
significand = show
end
return {
clean = '.' .. show,
exponent = exponent,
sign = sign,
show = sign .. with_exponent(parms, significand, exponent-1),
is_scientific = true,
}
end
if exponent >= #show then
show = show .. zeros(exponent - #show) -- result has no dot
elseif exponent <= 0 then
show = '0.' .. zeros(-exponent) .. show
else
show = show:sub(1, exponent) .. '.' .. show:sub(exponent+1)
end
end
local formatted_show
if tfrac then
show = tostring(tfrac.value) -- to set clean in returned table
formatted_show = format_fraction(parms, 'out', isnegative, tfrac.wholestr, tfrac.numstr, tfrac.denstr, parms.opt_spell_out)
else
if isnegative and show:match('^0.?0*$') then
sign = '' -- don't show minus if result is negative but rounds to zero
end
formatted_show = sign .. with_separator(parms, show)
if parms.opt_spell_out then
formatted_show = spell_number(parms, 'out', sign .. show) or formatted_show
end
end
return {
clean = show,
sign = sign,
show = formatted_show,
is_scientific = false, -- to avoid calling __index
}
end
local function extract_fraction(parms, text, negative)
-- If text represents a fraction, return
-- value, altvalue, show, denominator
-- where
-- value is a number (value of the fraction in argument text)
-- altvalue is an alternate interpretation of any fraction for the hands
-- unit where "12.1+3/4" means 12 hands 1.75 inches
-- show is a string (formatted text for display of an input value,
-- and is spelled if wanted and possible)
-- denominator is value of the denominator in the fraction
-- Otherwise, return nil.
-- Input uses en digits and '.' decimal mark (input has been translated).
-- Output uses digits in local language and local decimal mark, if any.
------------------------------------------------------------------------
-- Originally this function accepted x+y/z where x, y, z were any valid
-- numbers, possibly with a sign. For example '1.23e+2+1.2/2.4' = 123.5,
-- and '2-3/8' = 1.625. However, such usages were found to be errors or
-- misunderstandings, so since August 2014 the following restrictions apply:
-- x (if present) is an integer or has a single digit after decimal mark
-- y and z are unsigned integers
-- e-notation is not accepted
-- The overall number can start with '+' or '-' (so '12+3/4' and '+12+3/4'
-- and '-12-3/4' are valid).
-- Any leading negative sign is removed by the caller, so only inputs
-- like the following are accepted here (may have whitespace):
-- negative = false false true (there was a leading '-')
-- text = '2/3' '+2/3' '2/3'
-- text = '1+2/3' '+1+2/3' '1-2/3'
-- text = '12.3+1/2' '+12.3+1/2' '12.3-1/2'
-- Values like '12.3+1/2' are accepted, but are intended only for use
-- with the hands unit (not worth adding code to enforce that).
------------------------------------------------------------------------
local leading_plus, prefix, numstr, slashes, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*(/+)%s*(%d+)%s*$')
if not leading_plus then
-- Accept a single U+2044 fraction slash because that may be pasted.
leading_plus, prefix, numstr, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*⁄%s*(%d+)%s*$')
slashes = '/'
end
local numerator = tonumber(numstr)
local denominator = tonumber(denstr)
if numerator == nil or denominator == nil or (negative and leading_plus ~= '') then
return nil
end
local whole, wholestr
if prefix == '' then
wholestr = ''
whole = 0
else
-- Any prefix must be like '12+' or '12-' (whole number and fraction sign);
-- '12.3+' and '12.3-' are also accepted (single digit after decimal point)
-- because '12.3+1/2 hands' is valid (12 hands 3½ inches).
local num1, num2, frac_sign = prefix:match('^(%d+)(%.?%d?)%s*([+%-])$')
if num1 == nil then return nil end
if num2 == '' then -- num2 must be '' or like '.1' but not '.' or '.12'
wholestr = num1
else
if #num2 ~= 2 then return nil end
wholestr = num1 .. num2
end
if frac_sign ~= (negative and '-' or '+') then return nil end
whole = tonumber(wholestr)
if whole == nil then return nil end
end
local value = whole + numerator / denominator
if not valid_number(value) then return nil end
local altvalue = whole + numerator / (denominator * 10)
local style = #slashes -- kludge: 1 or 2 slashes can be used to select style
if style > 2 then style = 2 end
local wikitext = format_fraction(parms, 'in', negative, leading_plus .. wholestr, numstr, denstr, parms.opt_spell_in, style)
return value, altvalue, wikitext, denominator
end
local function extract_number(parms, text, another, no_fraction)
-- Return true, info if can extract a number from text,
-- where info is a table with the result,
-- or return false, t where t is an error message table.
-- Input can use en digits or digits in local language and can
-- have references at the end. Accepting references is intended
-- for use in infoboxes with a field for a value passed to convert.
-- Parameter another = true if the expected value is not the first.
-- Before processing, the input text is cleaned:
-- * Any thousand separators (valid or not) are removed.
-- * Any sign is replaced with '-' (if negative) or '' (otherwise).
-- That replaces Unicode minus with '-'.
-- If successful, the returned info table contains named fields:
-- value = a valid number
-- altvalue = a valid number, usually same as value but different
-- if fraction used (for hands unit)
-- singular = true if value is 1 or -1 (to use singular form of units)
-- clean = cleaned text with any separators and sign removed
-- (en digits and '.' decimal mark)
-- show = text formatted for output, possibly with ref strip markers
-- (digits in local language and custom decimal mark)
-- The resulting show:
-- * Is for an input value and is spelled if wanted and possible.
-- * Has a rounded value, if wanted.
-- * Has digits grouped where necessary, if wanted.
-- * If negative, a Unicode minus is used; otherwise the sign is
-- '+' (if the input text used '+'), or is '' (if no sign in input).
text = strip(text or '')
local reference
local pos = text:find('\127', 1, true)
if pos then
local before = text:sub(1, pos - 1)
local remainder = text:sub(pos)
local refs = {}
while #remainder > 0 do
local ref, spaces
ref, spaces, remainder = remainder:match('^(\127[^\127]*UNIQ[^\127]*%-ref[^\127]*\127)(%s*)(.*)')
if ref then
table.insert(refs, ref)
else
refs = {}
break
end
end
if #refs > 0 then
text = strip(before)
reference = table.concat(refs)
end
end
local clean = to_en(text, parms)
if clean == '' then
return false, { another and 'cvt_no_num2' or 'cvt_no_num' }
end
local isnegative, propersign = false, '' -- most common case
local singular, show, denominator
local value = tonumber(clean)
local altvalue
if value then
local sign = clean:sub(1, 1)
if sign == '+' or sign == '-' then
propersign = (sign == '+') and '+' or MINUS
clean = clean:sub(2)
end
if value < 0 then
isnegative = true
value = -value
end
else
local valstr
for _, prefix in ipairs({ '-', MINUS, '−' }) do
-- Including '-' sets isnegative in case input is a fraction like '-2-3/4'.
local plen = #prefix
if clean:sub(1, plen) == prefix then
valstr = clean:sub(plen + 1)
if valstr:match('^%s') then -- "- 1" is invalid but "-1 - 1/2" is ok
return false, { 'cvt_bad_num', text }
end
break
end
end
if valstr then
isnegative = true
propersign = MINUS
clean = valstr
value = tonumber(clean)
end
if value == nil then
if not no_fraction then
value, altvalue, show, denominator = extract_fraction(parms, clean, isnegative)
end
if value == nil then
return false, { 'cvt_bad_num', text }
end
if value <= 1 then
singular = true -- for example, "½ mile" or "one half mile" (singular unit)
end
end
end
if not valid_number(value) then -- for example, "1e310" may overflow
return false, { 'cvt_invalid_num' }
end
if show == nil then
-- clean is a non-empty string with no spaces, and does not represent a fraction,
-- and value = tonumber(clean) is a number >= 0.
-- If the input uses e-notation, show will be displayed using a power of ten, but
-- we use the number as given so it might not be normalized scientific notation.
-- The input value is spelled if specified so any e-notation is ignored;
-- that allows input like 2e6 to be spelled as "two million" which works
-- because the spell module converts '2e6' to '2000000' before spelling.
local function rounded(value, default, exponent)
local precision = parms.opt_ri
if precision then
local fmt = '%.' .. format('%d', precision) .. 'f'
local result = fmt:format(tonumber(value) + 2e-14) -- fudge for some common cases of bad rounding
if not exponent then
singular = (tonumber(result) == 1)
end
return result
end
return default
end
singular = (value == 1)
local scientific
local significand, exponent = clean:match('^([%d.]+)[Ee]([+%-]?%d+)')
if significand then
show = with_exponent(parms, rounded(significand, significand, exponent), exponent)
scientific = true
else
show = with_separator(parms, rounded(value, clean))
end
show = propersign .. show
if parms.opt_spell_in then
show = spell_number(parms, 'in', propersign .. rounded(value, clean)) or show
scientific = false
end
if scientific then
parms.opt_scientific = true
end
end
if isnegative and (value ~= 0) then
value = -value
altvalue = -(altvalue or value)
end
return true, {
value = value,
altvalue = altvalue or value,
singular = singular,
clean = clean,
show = show .. (reference or ''),
denominator = denominator,
}
end
local function get_number(text)
-- Return v, f where:
-- v = nil (text is not a number)
-- or
-- v = value of text (text is a number)
-- f = true if value is an integer
-- Input can use en digits or digits in local language or separators,
-- but no Unicode minus, and no fraction.
if text then
local number = tonumber(to_en(text))
if number then
local _, fracpart = math.modf(number)
return number, (fracpart == 0)
end
end
end
local function gcd(a, b)
-- Return the greatest common denominator for the given values,
-- which are known to be positive integers.
if a > b then
a, b = b, a
end
if a <= 0 then
return b
end
local r = b % a
if r <= 0 then
return a
end
if r == 1 then
return 1
end
return gcd(r, a)
end
local function fraction_table(value, denominator)
-- Return value as a string or a table:
-- * If result is a string, there is no fraction, and the result
-- is value formatted as a string of en digits.
-- * If result is a table, it represents a fraction with named fields:
-- wholestr, numstr, denstr (strings of en digits for integer, numerator, denominator).
-- The result is rounded to the nearest multiple of (1/denominator).
-- If the multiple is zero, no fraction is included.
-- No fraction is included if value is very large as the fraction would
-- be unhelpful, particularly if scientific notation is required.
-- Input value is a non-negative number.
-- Input denominator is a positive integer for the desired fraction.
if value <= 0 then
return '0'
end
if denominator <= 0 or value > 1e8 then
return format('%.2f', value)
end
local integer, decimals = math.modf(value)
local numerator = floor((decimals * denominator) +
0.5 + 2e-14) -- add fudge for some common cases of bad rounding
if numerator >= denominator then
integer = integer + 1
numerator = 0
end
local wholestr = tostring(integer)
if numerator > 0 then
local div = gcd(numerator, denominator)
if div > 1 then
numerator = numerator / div
denominator = denominator / div
end
return {
wholestr = (integer > 0) and wholestr or '',
numstr = tostring(numerator),
denstr = tostring(denominator),
value = value,
}
end
return wholestr
end
local function preunits(count, preunit1, preunit2)
-- If count is 1:
-- ignore preunit2
-- return p1
-- else:
-- preunit1 is used for preunit2 if the latter is empty
-- return p1, p2
-- where:
-- p1 is text to insert before the input unit
-- p2 is text to insert before the output unit
-- p1 or p2 may be nil to mean "no preunit"
-- Using '+' gives output like "5+ feet" (no space before, but space after).
local function withspace(text, wantboth)
-- Return text with space before and, if wantboth, after.
-- However, no space is added if there is a space or ' ' or '-'
-- at that position ('-' is for adjectival text).
-- There is also no space if text starts with '&'
-- (e.g. '°' would display a degree symbol with no preceding space).
local char = text:sub(1, 1)
if char == '&' then
return text -- an html entity can be used to specify the exact display
end
if not (char == ' ' or char == '-' or char == '+') then
text = ' ' .. text
end
if wantboth then
char = text:sub(-1, -1)
if not (char == ' ' or char == '-' or text:sub(-6, -1) == ' ') then
text = text .. ' '
end
end
return text
end
local PLUS = '+ '
preunit1 = preunit1 or ''
local trim1 = strip(preunit1)
if count == 1 then
if trim1 == '' then
return nil
end
if trim1 == '+' then
return PLUS
end
return withspace(preunit1, true)
end
preunit1 = withspace(preunit1)
preunit2 = preunit2 or ''
local trim2 = strip(preunit2)
if trim1 == '+' then
if trim2 == '' or trim2 == '+' then
return PLUS, PLUS
end
preunit1 = PLUS
end
if trim2 == '' then
if trim1 == '' then
return nil, nil
end
preunit2 = preunit1
elseif trim2 == '+' then
preunit2 = PLUS
elseif trim2 == ' ' then -- trick to make preunit2 empty
preunit2 = nil
else
preunit2 = withspace(preunit2)
end
return preunit1, preunit2
end
local function range_text(range, want_name, parms, before, after, inout, options)
-- Return before .. rtext .. after
-- where rtext is the text that separates two values in a range.
local rtext, adj_text, exception
options = options or {}
if type(range) == 'table' then
-- Table must specify range text for ('off' and 'on') or ('input' and 'output'),
-- and may specify range text for 'adj=on',
-- and may specify exception = true.
rtext = range[want_name and 'off' or 'on'] or
range[((inout == 'in') == (parms.opt_flip == true)) and 'output' or 'input']
adj_text = range['adj']
exception = range['exception']
else
rtext = range
end
if parms.opt_adjectival then
if want_name or (exception and parms.abbr_org == 'on') then
rtext = adj_text or rtext:gsub(' ', '-'):gsub(' ', '-')
end
end
if rtext == '–' and (options.spaced or after:sub(1, #MINUS) == MINUS) then
rtext = ' – '
end
return before .. rtext .. after
end
local function get_composite(parms, iparm, in_unit_table)
-- Look for a composite input unit. For example, {{convert|1|yd|2|ft|3|in}}
-- would result in a call to this function with
-- iparm = 3 (parms[iparm] = "2", just after the first unit)
-- in_unit_table = (unit table for "yd"; contains value 1 for number of yards)
-- Return true, iparm, unit where
-- iparm = index just after the composite units (7 in above example)
-- unit = composite unit table holding all input units,
-- or return true if no composite unit is present in parms,
-- or return false, t where t is an error message table.
local default, subinfo
local composite_units, count = { in_unit_table }, 1
local fixups = {}
local total = in_unit_table.valinfo[1].value
local subunit = in_unit_table
while subunit.subdivs do -- subdivs is nil or a table of allowed subdivisions
local subcode = strip(parms[iparm+1])
local subdiv = subunit.subdivs[subcode] or subunit.subdivs[(all_units[subcode] or {}).target]
if not subdiv then
break
end
local success
success, subunit = lookup(parms, subcode, 'no_combination')
if not success then return false, subunit end -- should never occur
success, subinfo = extract_number(parms, parms[iparm])
if not success then return false, subinfo end
iparm = iparm + 2
subunit.inout = 'in'
subunit.valinfo = { subinfo }
-- Recalculate total as a number of subdivisions.
-- subdiv[1] = number of subdivisions per previous unit (integer > 1).
total = total * subdiv[1] + subinfo.value
if not default then -- set by the first subdiv with a default defined
default = subdiv.default
end
count = count + 1
composite_units[count] = subunit
if subdiv.unit or subdiv.name then
fixups[count] = { unit = subdiv.unit, name = subdiv.name, valinfo = subunit.valinfo }
end
end
if count == 1 then
return true -- no error and no composite unit
end
for i, fixup in pairs(fixups) do
local unit = fixup.unit
local name = fixup.name
if not unit or (count > 2 and name) then
composite_units[i].fixed_name = name
else
local success, alternate = lookup(parms, unit, 'no_combination')
if not success then return false, alternate end -- should never occur
alternate.inout = 'in'
alternate.valinfo = fixup.valinfo
composite_units[i] = alternate
end
end
return true, iparm, {
utype = in_unit_table.utype,
scale = subunit.scale, -- scale of last (least significant) unit
valinfo = { { value = total, clean = subinfo.clean, denominator = subinfo.denominator } },
composite = composite_units,
default = default or in_unit_table.default
}
end
local function translate_parms(parms, kv_pairs)
-- Update fields in parms by translating each key:value in kv_pairs to terms
-- used by this module (may involve translating from local language to English).
-- Also, checks are performed which may display warnings, if enabled.
-- Return true if successful or return false, t where t is an error message table.
currency_text = nil -- local testing can hold module in memory; must clear globals
if kv_pairs.adj and kv_pairs.sing then
-- For enwiki (before translation), warn if attempt to use adj and sing
-- as the latter is a deprecated alias for the former.
if kv_pairs.adj ~= kv_pairs.sing and kv_pairs.sing ~= '' then
add_warning(parms, 1, 'cvt_unknown_option', 'sing=' .. kv_pairs.sing)
end
kv_pairs.sing = nil
end
kv_pairs.comma = kv_pairs.comma or config.comma -- for plwiki who want default comma=5
for loc_name, loc_value in pairs(kv_pairs) do
local en_name = text_code.en_option_name[loc_name]
if en_name then
local en_value = text_code.en_option_value[en_name]
if en_value == 'INTEGER' then -- altitude_ft, altitude_m, frac, sigfig
en_value = nil
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
else
local minimum
local number, is_integer = get_number(loc_value)
if en_name == 'sigfig' then
minimum = 1
elseif en_name == 'frac' then
minimum = 2
if number and number < 0 then
parms.opt_fraction_horizontal = true
number = -number
end
else
minimum = -1e6
end
if number and is_integer and number >= minimum then
en_value = number
else
local m
if en_name == 'frac' then
m = 'cvt_bad_frac'
elseif en_name == 'sigfig' then
m = 'cvt_bad_sigfig'
else
m = 'cvt_bad_altitude'
end
add_warning(parms, 1, m, loc_name .. '=' .. loc_value)
end
end
elseif en_value == 'TEXT' then -- $, input, qid, qual, stylein, styleout, tracking
en_value = loc_value ~= '' and loc_value or nil -- accept non-empty user text with no validation
if not en_value and (en_name == '$' or en_name == 'qid' or en_name == 'qual') then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
elseif en_name == '$' then
-- Value should be a single character like "€" for the euro currency symbol, but anything is accepted.
currency_text = (loc_value == 'euro') and '€' or loc_value
elseif en_name == 'input' then
-- May have something like {{convert|input=}} (empty input) if source is an infobox
-- with optional fields. In that case, want to output nothing rather than an error.
parms.input_text = loc_value -- keep input because parms.input is nil if loc_value == ''
end
else
en_value = en_value[loc_value]
if en_value and en_value:sub(-1) == '?' then
en_value = en_value:sub(1, -2)
add_warning(parms, -1, 'cvt_deprecated', loc_name .. '=' .. loc_value)
end
if en_value == nil then
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
else
add_warning(parms, 1, 'cvt_unknown_option', loc_name .. '=' .. loc_value)
end
elseif en_value == '' then
en_value = nil -- an ignored option like adj=off
elseif type(en_value) == 'string' and en_value:sub(1, 4) == 'opt_' then
for _, v in ipairs(split(en_value, ',')) do
local lhs, rhs = v:match('^(.-)=(.+)$')
if rhs then
parms[lhs] = tonumber(rhs) or rhs
else
parms[v] = true
end
end
en_value = nil
end
end
parms[en_name] = en_value
else
add_warning(parms, 1, 'cvt_unknown_option', loc_name .. '=' .. loc_value)
end
end
local abbr_entered = parms.abbr
local cfg_abbr = config.abbr
if cfg_abbr then
-- Don't warn if invalid because every convert would show that warning.
if cfg_abbr == 'on always' then
parms.abbr = 'on'
elseif cfg_abbr == 'off always' then
parms.abbr = 'off'
elseif parms.abbr == nil then
if cfg_abbr == 'on default' then
parms.abbr = 'on'
elseif cfg_abbr == 'off default' then
parms.abbr = 'off'
end
end
end
if parms.abbr then
if parms.abbr == 'unit' then
parms.abbr = 'on'
parms.number_word = true
end
parms.abbr_org = parms.abbr -- original abbr, before any flip
elseif parms.opt_hand_hh then
parms.abbr_org = 'on'
parms.abbr = 'on'
else
parms.abbr = 'out' -- default is to abbreviate output only (use symbol, not name)
end
if parms.opt_order_out then
-- Disable options that do not work in a useful way with order=out.
parms.opt_flip = nil -- override adj=flip
parms.opt_spell_in = nil
parms.opt_spell_out = nil
parms.opt_spell_upper = nil
end
if parms.opt_spell_out and not abbr_entered then
parms.abbr = 'off' -- should show unit name when spelling the output value
end
if parms.opt_flip then
local function swap_in_out(option)
local value = parms[option]
if value == 'in' then
parms[option] = 'out'
elseif value == 'out' then
parms[option] = 'in'
end
end
swap_in_out('abbr')
swap_in_out('lk')
if parms.opt_spell_in and not parms.opt_spell_out then
-- For simplicity, and because it does not appear to be needed,
-- user cannot set an option to spell the output only.
parms.opt_spell_in = nil
parms.opt_spell_out = true
end
end
if parms.opt_spell_upper then
parms.spell_upper = parms.opt_flip and 'out' or 'in'
end
if parms.opt_table or parms.opt_tablecen then
if abbr_entered == nil and parms.lk == nil then
parms.opt_values = true
end
parms.table_align = parms.opt_table and 'right' or 'center'
end
if parms.table_align or parms.opt_sortable_on then
parms.need_table_or_sort = true
end
local disp_joins = text_code.disp_joins
local default_joins = disp_joins['b']
parms.join_between = default_joins[3] or '; '
local disp = parms.disp
if disp == nil then -- special case for the most common setting
parms.joins = default_joins
elseif disp == 'x' then
-- Later, parms.joins is set from the input parameters.
else
-- Old template does this.
local abbr = parms.abbr
if disp == 'slash' then
if abbr_entered == nil then
disp = 'slash-nbsp'
elseif abbr == 'in' or abbr == 'out' then
disp = 'slash-sp'
else
disp = 'slash-nosp'
end
elseif disp == 'sqbr' then
if abbr == 'on' then
disp = 'sqbr-nbsp'
else
disp = 'sqbr-sp'
end
end
parms.joins = disp_joins[disp] or default_joins
parms.join_between = parms.joins[3] or parms.join_between
parms.wantname = parms.joins.wantname
end
if (en_default and not parms.opt_lang_local and (parms[1] or ''):find('%d')) or parms.opt_lang_en then
from_en_table = nil
end
if en_default and from_en_table then
-- For hiwiki: localized symbol/name is defined with the US symbol/name field,
-- and is used if output uses localized numbers.
parms.opt_sp_us = true
end
return true
end
local function get_values(parms)
-- If successful, update parms and return true, v, i where
-- v = table of input values
-- i = index to next entry in parms after those processed here
-- or return false, t where t is an error message table.
local valinfo = collection() -- numbered table of input values
local range = collection() -- numbered table of range items (having, for example, 2 range items requires 3 input values)
local had_nocomma -- true if removed "nocomma" kludge from second parameter (like "tonocomma")
local parm2 = strip(parms[2])
if parm2 and parm2:sub(-7, -1) == 'nocomma' then
parms[2] = strip(parm2:sub(1, -8))
parms.opt_nocomma = true
had_nocomma = true
end
local function extractor(i)
-- If the parameter is not a value, try unpacking it as a range ("1-23" for "1 to 23").
-- However, "-1-2/3" is a negative fraction (-1⅔), so it must be extracted first.
-- Do not unpack a parameter if it is like "3-1/2" which is sometimes incorrectly
-- used instead of "3+1/2" (and which should not be interpreted as "3 to ½").
-- Unpacked items are inserted into the parms table.
-- The tail recursion allows combinations like "1x2 to 3x4".
local valstr = strip(parms[i]) -- trim so any '-' as a negative sign will be at start
local success, result = extract_number(parms, valstr, i > 1)
if not success and valstr and i < 20 then -- check i to limit abuse
local lhs, sep, rhs = valstr:match('^(%S+)%s+(%S+)%s+(%S.*)')
if lhs and not (sep == '-' and rhs:match('/')) then
if sep:find('%d') then
return success, result -- to reject {{convert|1 234 567|m}} with a decent message (en only)
end
parms[i] = rhs
table.insert(parms, i, sep)
table.insert(parms, i, lhs)
return extractor(i)
end
if not valstr:match('%-.*/') then
for _, sep in ipairs(text_code.ranges.words) do
local start, stop = valstr:find(sep, 2, true) -- start at 2 to skip any negative sign for range '-'
if start then
parms[i] = valstr:sub(stop + 1)
table.insert(parms, i, sep)
table.insert(parms, i, valstr:sub(1, start - 1))
return extractor(i)
end
end
end
end
return success, result
end
local i = 1
local is_change
while true do
local success, info = extractor(i) -- need to set parms.opt_nocomma before calling this
if not success then return false, info end
i = i + 1
if is_change then
info.is_change = true -- value is after "±" and so is a change (significant for range like {{convert|5|±|5|°C}})
is_change = nil
end
valinfo:add(info)
local range_item = get_range(strip(parms[i]))
if not range_item then
break
end
i = i + 1
range:add(range_item)
if type(range_item) == 'table' then
-- For range "x", if append unit to some values, append it to all.
parms.in_range_x = parms.in_range_x or range_item.in_range_x
parms.out_range_x = parms.out_range_x or range_item.out_range_x
parms.abbr_range_x = parms.abbr_range_x or range_item.abbr_range_x
is_change = range_item.is_range_change
end
end
if range.n > 0 then
if range.n > 30 then -- limit abuse, although 4 is a more likely upper limit
return false, { 'cvt_invalid_num' } -- misleading message but it will do
end
parms.range = range
elseif had_nocomma then
return false, { 'cvt_unknown', parm2 }
end
return true, valinfo, i
end
local function simple_get_values(parms)
-- If input is like "{{convert|valid_value|valid_unit|...}}",
-- return true, i, in_unit, in_unit_table
-- i = index in parms of what follows valid_unit, if anything.
-- The valid_value is not negative and does not use a fraction, and
-- no options requiring further processing of the input are used.
-- Otherwise, return nothing or return false, parm1 for caller to interpret.
-- Testing shows this function is successful for 96% of converts in articles,
-- and that on average it speeds up converts by 8%.
local clean = to_en(strip(parms[1] or ''), parms)
if parms.opt_ri or parms.opt_spell_in or #clean > 10 or not clean:match('^[0-9.]+$') then
return false, clean
end
local value = tonumber(clean)
if not value then return end
local info = {
value = value,
altvalue = value,
singular = (value == 1),
clean = clean,
show = with_separator(parms, clean),
}
local in_unit = strip(parms[2])
local success, in_unit_table = lookup(parms, in_unit, 'no_combination')
if not success then return end
in_unit_table.valinfo = { info }
return true, 3, in_unit, in_unit_table
end
local function wikidata_call(parms, operation, ...)
-- Return true, s where s is the result of a Wikidata operation,
-- or return false, t where t is an error message table.
local function worker(...)
wikidata_code = wikidata_code or require(wikidata_module)
wikidata_data = wikidata_data or mw.loadData(wikidata_data_module)
return wikidata_code[operation](wikidata_data, ...)
end
local success, status, result = pcall(worker, ...)
if success then
return status, result
end
if parms.opt_sortable_debug then
-- Use debug=yes to crash if an error while accessing Wikidata.
error('Error accessing Wikidata: ' .. status, 0)
end
return false, { 'cvt_wd_fail' }
end
local function get_parms(parms, args)
-- If successful, update parms and return true, unit where
-- parms is a table of all arguments passed to the template
-- converted to named arguments, and
-- unit is the input unit table;
-- or return false, t where t is an error message table.
-- For special processing (not a convert), can also return
-- true, wikitext where wikitext is the final result.
-- The returned input unit table may be for a fake unit using the specified
-- unit code as the symbol and name, and with bad_mcode = message code table.
-- MediaWiki removes leading and trailing whitespace from the values of
-- named arguments. However, the values of numbered arguments include any
-- whitespace entered in the template, and whitespace is used by some
-- parameters (example: the numbered parameters associated with "disp=x").
local kv_pairs = {} -- table of input key:value pairs where key is a name; needed because cannot iterate parms and add new fields to it
for k, v in pairs(args) do
if type(k) == 'number' or k == 'test' then -- parameter "test" is reserved for testing and is not translated
parms[k] = v
else
kv_pairs[k] = v
end
end
if parms.test == 'wikidata' then
local ulookup = function (ucode)
-- Use empty table for parms so it does not accumulate results when used repeatedly.
return lookup({}, ucode, 'no_combination')
end
return wikidata_call(parms, '_listunits', ulookup)
end
local success, msg = translate_parms(parms, kv_pairs)
if not success then return false, msg end
if parms.input then
success, msg = wikidata_call(parms, '_adjustparameters', parms, 1)
if not success then return false, msg end
end
local success, i, in_unit, in_unit_table = simple_get_values(parms)
if not success then
if type(i) == 'string' and i:match('^NNN+$') then
-- Some infoboxes have examples like {{convert|NNN|m}} (3 or more "N").
-- Output an empty string for these.
return false, { 'cvt_no_output' }
end
local valinfo
success, valinfo, i = get_values(parms)
if not success then return false, valinfo end
in_unit = strip(parms[i])
i = i + 1
success, in_unit_table = lookup(parms, in_unit, 'no_combination')
if not success then
in_unit = in_unit or ''
if parms.opt_ignore_error then -- display given unit code with no error (for use with {{val}})
in_unit_table = '' -- suppress error message and prevent processing of output unit
end
in_unit_table = setmetatable({
symbol = in_unit, name2 = in_unit, utype = in_unit,
scale = 1, default = '', defkey = '', linkey = '',
bad_mcode = in_unit_table }, unit_mt)
end
in_unit_table.valinfo = valinfo
end
if parms.test == 'msg' then
-- Am testing the messages produced when no output unit is specified, and
-- the input unit has a missing or invalid default.
-- Set two units for testing that.
-- LATER: Remove this code.
if in_unit == 'chain' then
in_unit_table.default = nil -- no default
elseif in_unit == 'rd' then
in_unit_table.default = "ft!X!m" -- an invalid expression
end
end
in_unit_table.inout = 'in' -- this is an input unit
if not parms.range then
local success, inext, composite_unit = get_composite(parms, i, in_unit_table)
if not success then return false, inext end
if composite_unit then
in_unit_table = composite_unit
i = inext
end
end
if in_unit_table.builtin == 'mach' then
-- As with old template, a number following Mach as the input unit is the altitude.
-- That is deprecated: should use altitude_ft=NUMBER or altitude_m=NUMBER.
local success, info
success = tonumber(parms[i]) -- this will often work and will give correct result for values like 2e4 without forcing output scientific notation
if success then
info = { value = success }
else
success, info = extract_number(parms, parms[i], false, true)
end
if success then
i = i + 1
in_unit_table.altitude = info.value
end
end
local word = strip(parms[i])
i = i + 1
local precision, is_bad_precision
local function set_precision(text)
local number, is_integer = get_number(text)
if number then
if is_integer then
precision = number
else
precision = text
is_bad_precision = true
end
return true -- text was used for precision, good or bad
end
end
if word and not set_precision(word) then
parms.out_unit = parms.out_unit or word
if set_precision(strip(parms[i])) then
i = i + 1
end
end
if parms.opt_adj_mid then
word = parms[i]
i = i + 1
if word then -- mid-text words
if word:sub(1, 1) == '-' then
parms.mid = word
else
parms.mid = ' ' .. word
end
end
end
if parms.opt_one_preunit then
parms[parms.opt_flip and 'preunit2' or 'preunit1'] = preunits(1, parms[i])
i = i + 1
end
if parms.disp == 'x' then
-- Following is reasonably compatible with the old template.
local first = parms[i] or ''
local second = parms[i+1] or ''
i = i + 2
if strip(first) == '' then -- user can enter ' ' rather than ' ' to avoid the default
first = ' [ ' .. first
second = ' ]' .. second
end
parms.joins = { first, second }
elseif parms.opt_two_preunits then
local p1, p2 = preunits(2, parms[i], parms[i+1])
i = i + 2
if parms.preunit1 then
-- To simplify documentation, allow unlikely use of adj=pre with disp=preunit
-- (however, an output unit must be specified with adj=pre and with disp=preunit).
parms.preunit1 = parms.preunit1 .. p1
parms.preunit2 = p2
else
parms.preunit1, parms.preunit2 = p1, p2
end
end
if precision == nil then
if set_precision(strip(parms[i])) then
i = i + 1
end
end
if is_bad_precision then
add_warning(parms, 1, 'cvt_bad_prec', precision)
else
parms.precision = precision
end
for j = i, i + 3 do
local parm = parms[j] -- warn if find a non-empty extraneous parameter
if parm and parm:match('%S') then
add_warning(parms, 1, 'cvt_unknown_option', parm)
break
end
end
return true, in_unit_table
end
local function record_default_precision(parms, out_current, precision)
-- If necessary, adjust parameters and return a possibly adjusted precision.
-- When converting a range of values where a default precision is required,
-- that default is calculated for each value because the result sometimes
-- depends on the precise input and output values. This function may cause
-- the entire convert process to be repeated in order to ensure that the
-- same default precision is used for each individual convert.
-- If that were not done, a range like 1000 to 1000.4 may give poor results
-- because the first output could be heavily rounded, while the second is not.
-- For range 1000.4 to 1000, this function can give the second convert the
-- same default precision that was used for the first.
if not parms.opt_round_each then
local maxdef = out_current.max_default_precision
if maxdef then
if maxdef < precision then
parms.do_convert_again = true
out_current.max_default_precision = precision
else
precision = out_current.max_default_precision
end
else
out_current.max_default_precision = precision
end
end
return precision
end
local function default_precision(parms, invalue, inclean, denominator, outvalue, in_current, out_current, extra)
-- Return a default value for precision (an integer like 2, 0, -2).
-- If denominator is not nil, it is the value of the denominator in inclean.
-- Code follows procedures used in old template.
local fudge = 1e-14 -- {{Order of magnitude}} adds this, so we do too
local prec, minprec, adjust
local subunit_ignore_trailing_zero
local subunit_more_precision -- kludge for "in" used in input like "|2|ft|6|in"
local composite = in_current.composite
if composite then
subunit_ignore_trailing_zero = true -- input "|2|st|10|lb" has precision 0, not -1
if composite[#composite].exception == 'subunit_more_precision' then
subunit_more_precision = true -- do not use standard precision with input like "|2|ft|6|in"
end
end
if denominator and denominator > 0 then
prec = math.max(log10(denominator), 1)
else
-- Count digits after decimal mark, handling cases like '12.345e6'.
local exponent
local integer, dot, decimals, expstr = inclean:match('^(%d*)(%.?)(%d*)(.*)')
local e = expstr:sub(1, 1)
if e == 'e' or e == 'E' then
exponent = tonumber(expstr:sub(2))
end
if dot == '' then
prec = subunit_ignore_trailing_zero and 0 or -integer:match('0*$'):len()
else
prec = #decimals
end
if exponent then
-- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5.
prec = prec - exponent
end
end
if in_current.istemperature and out_current.istemperature then
-- Converting between common temperatures (°C, °F, °R, K); not keVT.
-- Kelvin value can be almost zero, or small but negative due to precision problems.
-- Also, an input value like -300 C (below absolute zero) gives negative kelvins.
-- Calculate minimum precision from absolute value.
adjust = 0
local kelvin = abs((invalue - in_current.offset) * in_current.scale)
if kelvin < 1e-8 then -- assume nonzero due to input or calculation precision problem
minprec = 2
else
minprec = 2 - floor(log10(kelvin) + fudge) -- 3 sigfigs in kelvin
end
else
if invalue == 0 or outvalue <= 0 then
-- We are never called with a negative outvalue, but it might be zero.
-- This is special-cased to avoid calculation exceptions.
return record_default_precision(parms, out_current, 0)
end
if out_current.exception == 'integer_more_precision' and floor(invalue) == invalue then
-- With certain output units that sometimes give poor results
-- with default rounding, use more precision when the input
-- value is equal to an integer. An example of a poor result
-- is when input 50 gives a smaller output than input 49.5.
-- Experiment shows this helps, but it does not eliminate all
-- surprises because it is not clear whether "50" should be
-- interpreted as "from 45 to 55" or "from 49.5 to 50.5".
adjust = -log10(in_current.scale)
elseif subunit_more_precision then
-- Conversion like "{{convert|6|ft|1|in|cm}}" (where subunit is "in")
-- has a non-standard adjust value, to give more output precision.
adjust = log10(out_current.scale) + 2
else
adjust = log10(abs(invalue / outvalue))
end
adjust = adjust + log10(2)
-- Ensure that the output has at least two significant figures.
minprec = 1 - floor(log10(outvalue) + fudge)
end
if extra then
adjust = extra.adjust or adjust
minprec = extra.minprec or minprec
end
return record_default_precision(parms, out_current, math.max(floor(prec + adjust), minprec))
end
local function convert(parms, invalue, info, in_current, out_current)
-- Convert given input value from one unit to another.
-- Return output_value (a number) if a simple convert, or
-- return f, t where
-- f = true, t = table of information with results, or
-- f = false, t = error message table.
local inscale = in_current.scale
local outscale = out_current.scale
if not in_current.iscomplex and not out_current.iscomplex then
return invalue * (inscale / outscale) -- minimize overhead for most common case
end
if in_current.invert or out_current.invert then
-- Inverted units, such as inverse length, inverse time, or
-- fuel efficiency. Built-in units do not have invert set.
if (in_current.invert or 1) * (out_current.invert or 1) < 0 then
return 1 / (invalue * inscale * outscale)
end
return invalue * (inscale / outscale)
elseif in_current.offset then
-- Temperature (there are no built-ins for this type of unit).
if info.is_change then
return invalue * (inscale / outscale)
end
return (invalue - in_current.offset) * (inscale / outscale) + out_current.offset
else
-- Built-in unit.
local in_builtin = in_current.builtin
local out_builtin = out_current.builtin
if in_builtin and out_builtin then
if in_builtin == out_builtin then
return invalue
end
-- There are no cases (yet) where need to convert from one
-- built-in unit to another, so this should never occur.
return false, { 'cvt_bug_convert' }
end
if in_builtin == 'mach' or out_builtin == 'mach' then
-- Should check that only one altitude is given but am planning to remove
-- in_current.altitude (which can only occur when Mach is the input unit),
-- and out_current.altitude cannot occur.
local alt = parms.altitude_ft or in_current.altitude
if not alt and parms.altitude_m then
alt = parms.altitude_m / 0.3048 -- 1 ft = 0.3048 m
end
local spd = speed_of_sound(alt)
if in_builtin == 'mach' then
inscale = spd
return invalue * (inscale / outscale)
end
outscale = spd
local adjust = 0.1 / inscale
return true, {
outvalue = invalue * (inscale / outscale),
adjust = log10(adjust) + log10(2),
}
elseif in_builtin == 'hand' then
-- 1 hand = 4 inches; 1.2 hands = 6 inches.
-- Decimals of a hand are only defined for the first digit, and
-- the first fractional digit should be a number of inches (1, 2 or 3).
-- However, this code interprets the entire fractional part as the number
-- of inches / 10 (so 1.75 inches would be 0.175 hands).
-- A value like 12.3 hands is exactly 12*4 + 3 inches; base default precision on that.
local integer, fracpart = math.modf(invalue)
local inch_value = 4 * integer + 10 * fracpart -- equivalent number of inches
local factor = inscale / outscale
if factor == 4 then
-- Am converting to inches: show exact result, and use "inches" not "in" by default.
if parms.abbr_org == nil then
out_current.usename = true
end
local show = format('%g', abs(inch_value)) -- show and clean are unsigned
if not show:find('e', 1, true) then
return true, {
invalue = inch_value,
outvalue = inch_value,
clean = show,
show = show,
}
end
end
local outvalue = (integer + 2.5 * fracpart) * factor
local fracstr = info.clean:match('%.(.*)') or ''
local fmt
if fracstr == '' then
fmt = '%.0f'
else
fmt = '%.' .. format('%d', #fracstr - 1) .. 'f'
end
return true, {
invalue = inch_value,
clean = format(fmt, inch_value),
outvalue = outvalue,
minprec = 0,
}
end
end
return false, { 'cvt_bug_convert' } -- should never occur
end
local function user_style(parms, i)
-- Return text for a user-specified style for a table cell, or '' if none,
-- given i = 1 (input style) or 2 (output style).
local style = parms[(i == 1) and 'stylein' or 'styleout']
if style then
style = style:gsub('"', '')
if style ~= '' then
if style:sub(-1) ~= ';' then
style = style .. ';'
end
return style
end
end
return ''
end
local function make_table_or_sort(parms, invalue, info, in_current, scaled_top)
-- Set options to handle output for a table or a sort key, or both.
-- The text sort key is based on the value resulting from converting
-- the input to a fake base unit with scale = 1, and other properties
-- required for a conversion derived from the input unit.
-- For other modules, return the sort key in a hidden span element, and
-- the scaled value used to generate the sort key.
-- If scaled_top is set, it is the scaled value of the numerator of a per unit
-- to be combined with this unit (the denominator) to make the sort key.
-- Scaling only works with units that convert with a factor (not temperature).
local sortkey, scaled_value
if parms.opt_sortable_on then
local base = { -- a fake unit with enough fields for a valid convert
scale = 1,
invert = in_current.invert and 1,
iscomplex = in_current.iscomplex,
offset = in_current.offset and 0,
}
local outvalue, extra = convert(parms, invalue, info, in_current, base)
if extra then
outvalue = extra.outvalue
end
if in_current.istemperature then
-- Have converted to kelvin; assume numbers close to zero have a
-- rounding error and should be zero.
if abs(outvalue) < 1e-12 then
outvalue = 0
end
end
if scaled_top and outvalue ~= 0 then
outvalue = scaled_top / outvalue
end
scaled_value = outvalue
if not valid_number(outvalue) then
if outvalue < 0 then
sortkey = '1000000000000000000'
else
sortkey = '9000000000000000000'
end
elseif outvalue == 0 then
sortkey = '5000000000000000000'
else
local mag = floor(log10(abs(outvalue)) + 1e-14)
local prefix
if outvalue > 0 then
prefix = 7000 + mag
else
prefix = 2999 - mag
outvalue = outvalue + 10^(mag+1)
end
sortkey = format('%d', prefix) .. format('%015.0f', floor(outvalue * 10^(14-mag)))
end
end
local sortspan
if sortkey and not parms.table_align then
sortspan = parms.opt_sortable_debug and
'<span data-sort-value="' .. sortkey .. '♠"><span style="border:1px solid">' .. sortkey .. '♠</span></span>' or
'<span data-sort-value="' .. sortkey .. '♠"></span>'
parms.join_before = sortspan
end
if parms.table_align then
local sort
if sortkey then
sort = ' data-sort-value="' .. sortkey .. '"'
if parms.opt_sortable_debug then
parms.join_before = '<span style="border:1px solid">' .. sortkey .. '</span>'
end
else
sort = ''
end
local style = 'style="text-align:' .. parms.table_align .. ';'
local joins = {}
for i = 1, 2 do
joins[i] = (i == 1 and '' or '\n|') .. style .. user_style(parms, i) .. '"' .. sort .. '|'
end
parms.table_joins = joins
end
return sortspan, scaled_value
end
local cvt_to_hand
local function cvtround(parms, info, in_current, out_current)
-- Return true, t where t is a table with the conversion results; fields:
-- show = rounded, formatted string with the result of converting value in info,
-- using the rounding specified in parms.
-- singular = true if result (after rounding and ignoring any negative sign)
-- is "1", or like "1.00", or is a fraction with value < 1;
-- (and more fields shown below, and a calculated 'absvalue' field).
-- or return false, t where t is an error message table.
-- Input info.clean uses en digits (it has been translated, if necessary).
-- Output show uses en or non-en digits as appropriate, or can be spelled.
if out_current.builtin == 'hand' then
return cvt_to_hand(parms, info, in_current, out_current)
end
local invalue = in_current.builtin == 'hand' and info.altvalue or info.value
local outvalue, extra = convert(parms, invalue, info, in_current, out_current)
if parms.need_table_or_sort then
parms.need_table_or_sort = nil -- process using first input value only
make_table_or_sort(parms, invalue, info, in_current)
end
if extra then
if not outvalue then return false, extra end
invalue = extra.invalue or invalue
outvalue = extra.outvalue
end
if not valid_number(outvalue) then
return false, { 'cvt_invalid_num' }
end
local isnegative
if outvalue < 0 then
isnegative = true
outvalue = -outvalue
end
local precision, show, exponent
local denominator = out_current.frac
if denominator then
show = fraction_table(outvalue, denominator)
else
precision = parms.precision
if not precision then
if parms.sigfig then
show, exponent = make_sigfig(outvalue, parms.sigfig)
elseif parms.opt_round then
local n = parms.opt_round
if n == 0.5 then
local integer, fracpart = math.modf(floor(2 * outvalue + 0.5) / 2)
if fracpart == 0 then
show = format('%.0f', integer)
else
show = format('%.1f', integer + fracpart)
end
else
show = format('%.0f', floor((outvalue / n) + 0.5) * n)
end
elseif in_current.builtin == 'mach' then
local sigfig = info.clean:gsub('^[0.]+', ''):gsub('%.', ''):len() + 1
show, exponent = make_sigfig(outvalue, sigfig)
else
local inclean = info.clean
if extra then
inclean = extra.clean or inclean
show = extra.show
end
if not show then
precision = default_precision(parms, invalue, inclean, info.denominator, outvalue, in_current, out_current, extra)
end
end
end
end
if precision then
if precision >= 0 then
local fudge
if precision <= 8 then
-- Add a fudge to handle common cases of bad rounding due to inability
-- to precisely represent some values. This makes the following work:
-- {{convert|-100.1|C|K}} and {{convert|5555000|um|m|2}}.
-- Old template uses #expr round, which invokes PHP round().
-- LATER: Investigate how PHP round() works.
fudge = 2e-14
else
fudge = 0
end
local fmt = '%.' .. format('%d', precision) .. 'f'
local success
success, show = pcall(format, fmt, outvalue + fudge)
if not success then
return false, { 'cvt_big_prec', tostring(precision) }
end
else
precision = -precision -- #digits to zero (in addition to any digits after dot)
local shift = 10 ^ precision
show = format('%.0f', outvalue/shift)
if show ~= '0' then
exponent = #show + precision
end
end
end
local t = format_number(parms, show, exponent, isnegative)
if type(show) == 'string' then
-- Set singular using match because on some systems 0.99999999999999999 is 1.0.
if exponent then
t.singular = (exponent == 1 and show:match('^10*$'))
else
t.singular = (show == '1' or show:match('^1%.0*$'))
end
else
t.fraction_table = show
t.singular = (outvalue <= 1) -- cannot have 'fraction == 1', but if it were possible it would be singular
end
t.raw_absvalue = outvalue -- absolute value before rounding
return true, setmetatable(t, {
__index = function (self, key)
if key == 'absvalue' then
-- Calculate absolute value after rounding, if needed.
local clean, exponent = rawget(self, 'clean'), rawget(self, 'exponent')
local value = tonumber(clean) -- absolute value (any negative sign has been ignored)
if exponent then
value = value * 10^exponent
end
rawset(self, key, value)
return value
end
end })
end
function cvt_to_hand(parms, info, in_current, out_current)
-- Convert input to hands, inches.
-- Return true, t where t is a table with the conversion results;
-- or return false, t where t is an error message table.
if parms.abbr_org == nil then
out_current.usename = true -- default is to show name not symbol
end
local precision = parms.precision
local frac = out_current.frac
if not frac and precision and precision > 1 then
frac = (precision == 2) and 2 or 4
end
local out_next = out_current.out_next
if out_next then
-- Use magic knowledge to determine whether the next unit is inches without requiring i18n.
-- The following ensures that when the output combination "hand in" is used, the inches
-- value is rounded to match the hands value. Also, displaying say "61½" instead of 61.5
-- is better as 61.5 implies the value is not 61.4.
if out_next.exception == 'subunit_more_precision' then
out_next.frac = frac
end
end
-- Convert to inches; calculate hands from that.
local dummy_unit_table = { scale = out_current.scale / 4, frac = frac }
local success, outinfo = cvtround(parms, info, in_current, dummy_unit_table)
if not success then return false, outinfo end
local tfrac = outinfo.fraction_table
local inches = outinfo.raw_absvalue
if tfrac then
inches = floor(inches) -- integer part only; fraction added later
else
inches = floor(inches + 0.5) -- a hands measurement never shows decimals of an inch
end
local hands, inches = divide(inches, 4)
outinfo.absvalue = hands + inches/4 -- supposed to be the absolute rounded value, but this is close enough
local inchstr = tostring(inches) -- '0', '1', '2' or '3'
if precision and precision <= 0 then -- using negative or 0 for precision rounds to nearest hand
hands = floor(outinfo.raw_absvalue/4 + 0.5)
inchstr = ''
elseif tfrac then
-- Always show an integer before fraction (like "15.0½") because "15½" means 15-and-a-half hands.
inchstr = numdot .. format_fraction(parms, 'out', false, inchstr, tfrac.numstr, tfrac.denstr)
else
inchstr = numdot .. from_en(inchstr)
end
outinfo.show = outinfo.sign .. with_separator(parms, format('%.0f', hands)) .. inchstr
return true, outinfo
end
local function evaluate_condition(value, condition)
-- Return true or false from applying a conditional expression to value,
-- or throw an error if invalid.
-- A very limited set of expressions is supported:
-- v < 9
-- v * 9 < 9
-- where
-- 'v' is replaced with value
-- 9 is any number (as defined by Lua tonumber)
-- only en digits are accepted
-- '<' can also be '<=' or '>' or '>='
-- In addition, the following form is supported:
-- LHS and RHS
-- where
-- LHS, RHS = any of above expressions.
local function compare(value, text)
local arithop, factor, compop, limit = text:match('^%s*v%s*([*]?)(.-)([<>]=?)(.*)$')
if arithop == nil then
error('Invalid default expression', 0)
elseif arithop == '*' then
factor = tonumber(factor)
if factor == nil then
error('Invalid default expression', 0)
end
value = value * factor
end
limit = tonumber(limit)
if limit == nil then
error('Invalid default expression', 0)
end
if compop == '<' then
return value < limit
elseif compop == '<=' then
return value <= limit
elseif compop == '>' then
return value > limit
elseif compop == '>=' then
return value >= limit
end
error('Invalid default expression', 0) -- should not occur
end
local lhs, rhs = condition:match('^(.-%W)and(%W.*)')
if lhs == nil then
return compare(value, condition)
end
return compare(value, lhs) and compare(value, rhs)
end
local function get_default(value, unit_table)
-- Return true, s where s = name of unit's default output unit,
-- or return false, t where t is an error message table.
-- Some units have a default that depends on the input value
-- (the first value if a range of values is used).
-- If '!' is in the default, the first bang-delimited field is an
-- expression that uses 'v' to represent the input value.
-- Example: 'v < 120 ! small ! big ! suffix' (suffix is optional)
-- evaluates 'v < 120' as a boolean with result
-- 'smallsuffix' if (value < 120), or 'bigsuffix' otherwise.
-- Input must use en digits and '.' decimal mark.
local default = data_code.default_exceptions[unit_table.defkey or unit_table.symbol] or unit_table.default
if not default then
local per = unit_table.per
if per then
local function a_default(v, u)
local success, ucode = get_default(v, u)
if not success then
return '?' -- an unlikely error has occurred; will cause lookup of default to fail
end
-- Attempt to use only the first unit if a combination or output multiple.
-- This is not bulletproof but should work for most cases.
-- Where it does not work, the convert will need to specify the wanted output unit.
local t = all_units[ucode]
if t then
local combo = t.combination
if combo then
-- For a multiple like ftin, the "first" unit (ft) is last in the combination.
local i = t.multiple and table_len(combo) or 1
ucode = combo[i]
end
else
-- Try for an automatically generated combination.
local item = ucode:match('^(.-)%+') or ucode:match('^(%S+)%s')
if all_units[item] then
return item
end
end
return ucode
end
local unit1, unit2 = per[1], per[2]
local def1 = (unit1 and a_default(value, unit1) or unit_table.vprefix or '')
local def2 = a_default(1, unit2) -- 1 because per unit of denominator
return true, def1 .. '/' .. def2
end
return false, { 'cvt_no_default', unit_table.symbol }
end
if default:find('!', 1, true) == nil then
return true, default
end
local t = split(default, '!')
if #t == 3 or #t == 4 then
local success, result = pcall(evaluate_condition, value, t[1])
if success then
default = result and t[2] or t[3]
if #t == 4 then
default = default .. t[4]
end
return true, default
end
end
return false, { 'cvt_bad_default', unit_table.symbol }
end
local linked_pages -- to record linked pages so will not link to the same page more than once
local function unlink(unit_table)
-- Forget that the given unit has previously been linked (if it has).
-- That is needed when processing a range of inputs or outputs when an id
-- for the first range value may have been evaluated, but only an id for
-- the last value is displayed, and that id may need to be linked.
linked_pages[unit_table.unitcode or unit_table] = nil
end
local function make_link(link, id, unit_table)
-- Return wikilink "[[link|id]]", possibly abbreviated as in examples:
-- [[Mile|mile]] --> [[mile]]
-- [[Mile|miles]] --> [[mile]]s
-- However, just id is returned if:
-- * no link given (so caller does not need to check if a link was defined); or
-- * link has previously been used during the current convert (to avoid overlinking).
local link_key
if unit_table then
link_key = unit_table.unitcode or unit_table
else
link_key = link
end
if not link or link == '' or linked_pages[link_key] then
return id
end
linked_pages[link_key] = true
-- Following only works for language en, but it should be safe on other wikis,
-- and overhead of doing it generally does not seem worthwhile.
local l = link:sub(1, 1):lower() .. link:sub(2)
if link == id or l == id then
return '[[' .. id .. ']]'
elseif link .. 's' == id or l .. 's' == id then
return '[[' .. id:sub(1, -2) .. ']]s'
else
return '[[' .. link .. '|' .. id .. ']]'
end
end
local function variable_name(clean, unit_table)
-- For slwiki, a unit name depends on the value.
-- Parameter clean is the unsigned rounded value in en digits, as a string.
-- Value Source Example for "m"
-- integer 1: name1 meter (also is the name of the unit)
-- integer 2: var{1} metra
-- integer 3 and 4: var{2} metri
-- integer else: var{3} metrov (0 and 5 or more)
-- real/fraction: var{4} metra
-- var{i} means the i'th field in unit_table.varname if it exists and has
-- an i'th field, otherwise name2.
-- Fields are separated with "!" and are not empty.
-- A field for a unit using an SI prefix has the prefix name inserted,
-- replacing '#' if found, or before the field otherwise.
local vname
if clean == '1' then
vname = unit_table.name1
elseif unit_table.varname then
local i
if clean == '2' then
i = 1
elseif clean == '3' or clean == '4' then
i = 2
elseif clean:find('.', 1, true) then
i = 4
else
i = 3
end
if i > 1 and varname == 'pl' then
i = i - 1
end
vname = split(unit_table.varname, '!')[i]
end
if vname then
local si_name = rawget(unit_table, 'si_name') or ''
local pos = vname:find('#', 1, true)
if pos then
vname = vname:sub(1, pos - 1) .. si_name .. vname:sub(pos + 1)
else
vname = si_name .. vname
end
return vname
end
return unit_table.name2
end
local function linked_id(parms, unit_table, key_id, want_link, clean)
-- Return final unit id (symbol or name), optionally with a wikilink,
-- and update unit_table.sep if required.
-- key_id is one of: 'symbol', 'sym_us', 'name1', 'name1_us', 'name2', 'name2_us'.
local abbr_on = (key_id == 'symbol' or key_id == 'sym_us')
if abbr_on and want_link then
local symlink = rawget(unit_table, 'symlink')
if symlink then
return symlink -- for exceptions that have the linked symbol built-in
end
end
local multiplier = rawget(unit_table, 'multiplier')
local per = unit_table.per
if per then
local paren1, paren2 = '', '' -- possible parentheses around bottom unit
local unit1 = per[1] -- top unit_table, or nil
local unit2 = per[2] -- bottom unit_table
if abbr_on then
if not unit1 then
unit_table.sep = '' -- no separator in "$2/acre"
end
if not want_link then
local symbol = unit_table.symbol_raw
if symbol then
return symbol -- for exceptions that have the symbol built-in
end
end
if (unit2.symbol):find('⋅', 1, true) then
paren1, paren2 = '(', ')'
end
end
local key_id2 -- unit2 is always singular
if key_id == 'name2' then
key_id2 = 'name1'
elseif key_id == 'name2_us' then
key_id2 = 'name1_us'
else
key_id2 = key_id
end
local result
if abbr_on then
result = '/'
elseif omitsep then
result = per_word
elseif unit1 then
result = ' ' .. per_word .. ' '
else
result = per_word .. ' '
end
if want_link and unit_table.link then
if abbr_on or not varname then
result = (unit1 and linked_id(parms, unit1, key_id, false, clean) or '') .. result .. linked_id(parms, unit2, key_id2, false, '1')
else
result = (unit1 and variable_name(clean, unit1) or '') .. result .. variable_name('1', unit2)
end
if omit_separator(result) then
unit_table.sep = ''
end
return make_link(unit_table.link, result, unit_table)
end
if unit1 then
result = linked_id(parms, unit1, key_id, want_link, clean) .. result
if unit1.sep then
unit_table.sep = unit1.sep
end
elseif omitsep then
unit_table.sep = ''
end
return result .. paren1 .. linked_id(parms, unit2, key_id2, want_link, '1') .. paren2
end
if multiplier then
-- A multiplier (like "100" in "100km") forces the unit to be plural.
multiplier = from_en(multiplier)
if not omitsep then
multiplier = multiplier .. (abbr_on and ' ' or ' ')
end
if not abbr_on then
if key_id == 'name1' then
key_id = 'name2'
elseif key_id == 'name1_us' then
key_id = 'name2_us'
end
end
else
multiplier = ''
end
local id = unit_table.fixed_name or ((varname and not abbr_on) and variable_name(clean, unit_table) or unit_table[key_id])
if omit_separator(id) then
unit_table.sep = ''
end
if want_link then
local link = data_code.link_exceptions[unit_table.linkey or unit_table.symbol] or unit_table.link
if link then
local before = ''
local i = unit_table.customary
if i == 1 and parms.opt_sp_us then
i = 2 -- show "U.S." not "US"
end
if i == 3 and abbr_on then
i = 4 -- abbreviate "imperial" to "imp"
end
local customary = text_code.customary_units[i]
if customary then
-- LATER: This works for language en only, but it's esoteric so ignore for now.
local pertext
if id:sub(1, 1) == '/' then
-- Want unit "/USgal" to display as "/U.S. gal", not "U.S. /gal".
pertext = '/'
id = id:sub(2)
elseif id:sub(1, 4) == 'per ' then
-- Similarly want "per U.S. gallon", not "U.S. per gallon" (but in practice this is unlikely to be used).
pertext = 'per '
id = id:sub(5)
else
pertext = ''
end
-- Omit any "US"/"U.S."/"imp"/"imperial" from start of id since that will be inserted.
local removes = (i < 3) and { 'US ', 'US ', 'U.S. ', 'U.S. ' } or { 'imp ', 'imp ', 'imperial ' }
for _, prefix in ipairs(removes) do
local plen = #prefix
if id:sub(1, plen) == prefix then
id = id:sub(plen + 1)
break
end
end
before = pertext .. make_link(customary.link, customary[1]) .. ' '
end
id = before .. make_link(link, id, unit_table)
end
end
return multiplier .. id
end
local function make_id(parms, which, unit_table)
-- Return id, f where
-- id = unit name or symbol, possibly modified
-- f = true if id is a name, or false if id is a symbol
-- using the value for index 'which', and for 'in' or 'out' (unit_table.inout).
-- Result is '' if no symbol/name is to be used.
-- In addition, set unit_table.sep = ' ' or ' ' or ''
-- (the separator that caller will normally insert before the id).
if parms.opt_values then
unit_table.sep = ''
return ''
end
local inout = unit_table.inout
local info = unit_table.valinfo[which]
local abbr_org = parms.abbr_org
local adjectival = parms.opt_adjectival
local lk = parms.lk
local want_link = (lk == 'on' or lk == inout)
local usename = unit_table.usename
local singular = info.singular
local want_name
if usename then
want_name = true
else
if abbr_org == nil then
if parms.wantname then
want_name = true
end
if unit_table.usesymbol then
want_name = false
end
end
if want_name == nil then
local abbr = parms.abbr
if abbr == 'on' or abbr == inout or (abbr == 'mos' and inout == 'out') then
want_name = false
else
want_name = true
end
end
end
local key
if want_name then
if lk == nil and unit_table.builtin == 'hand' then
want_link = true
end
if parms.opt_use_nbsp then
unit_table.sep = ' '
else
unit_table.sep = ' '
end
if parms.opt_singular then
local value
if inout == 'in' then
value = info.value
else
value = info.absvalue
end
if value then -- some unusual units do not always set value field
value = abs(value)
singular = (0 < value and value < 1.0001)
end
end
if unit_table.engscale then
-- engscale: so "|1|e3kg" gives "1 thousand kilograms" (plural)
singular = false
end
key = (adjectival or singular) and 'name1' or 'name2'
if parms.opt_sp_us then
key = key .. '_us'
end
else
if unit_table.builtin == 'hand' then
if parms.opt_hand_hh then
unit_table.symbol = 'hh' -- LATER: might want i18n applied to this
end
end
unit_table.sep = ' '
key = parms.opt_sp_us and 'sym_us' or 'symbol'
end
return linked_id(parms, unit_table, key, want_link, info.clean), want_name
end
local function decorate_value(parms, unit_table, which, number_word)
-- If needed, update unit_table so values will be shown with extra information.
-- For consistency with the old template (but different from fmtpower),
-- the style to display powers of 10 includes "display:none" to allow some
-- browsers to copy, for example, "10³" as "10^3", rather than as "103".
local info
local engscale = unit_table.engscale
local prefix = unit_table.vprefix
if engscale or prefix then
info = unit_table.valinfo[which]
if info.decorated then
return -- do not redecorate if repeating convert
end
info.decorated = true
if engscale then
local inout = unit_table.inout
local abbr = parms.abbr
if (abbr == 'on' or abbr == inout) and not parms.number_word then
info.show = info.show ..
'<span style="margin-left:0.2em">×<span style="margin-left:0.1em">' ..
from_en('10') ..
'</span></span><s style="display:none">^</s><sup>' ..
from_en(tostring(engscale.exponent)) .. '</sup>'
elseif number_word then
local number_id
local lk = parms.lk
if lk == 'on' or lk == inout then
number_id = make_link(engscale.link, engscale[1])
else
number_id = engscale[1]
end
-- WP:NUMERAL recommends " " in values like "12 million".
info.show = info.show .. (parms.opt_adjectival and '-' or ' ') .. number_id
end
end
if prefix then
info.show = prefix .. info.show
end
end
end
local function process_input(parms, in_current)
-- Processing required once per conversion.
-- Return block of text to represent input (value/unit).
if parms.opt_output_only or parms.opt_output_number_only or parms.opt_output_unit_only then
parms.joins = { '', '' }
return ''
end
local first_unit
local composite = in_current.composite -- nil or table of units
if composite then
first_unit = composite[1]
else
first_unit = in_current
end
local id1, want_name = make_id(parms, 1, first_unit)
local sep = first_unit.sep -- separator between value and unit, set by make_id
local preunit = parms.preunit1
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_input_unit_only then
parms.joins = { '', '' }
if composite then
local parts = { id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, (make_id(parms, 1, unit)))
end
end
id1 = table.concat(parts, ' ')
end
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if parms.opt_also_symbol and not composite and not parms.opt_flip then
local join1 = parms.joins[1]
if join1 == ' (' or join1 == ' [' then
parms.joins = { ' [' .. first_unit[parms.opt_sp_us and 'sym_us' or 'symbol'] .. ']' .. join1 , parms.joins[2] }
end
end
if in_current.builtin == 'mach' and first_unit.sep ~= '' then -- '' means omitsep with non-enwiki name
local prefix = id1 .. ' '
local range = parms.range
local valinfo = first_unit.valinfo
local result = prefix .. valinfo[1].show
if range then
-- For simplicity and because more not needed, handle one range item only.
local prefix2 = make_id(parms, 2, first_unit) .. ' '
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in', {spaced=true})
end
return preunit .. result
end
if composite then
-- Simplify: assume there is no range, and no decoration.
local mid = (not parms.opt_flip) and parms.mid or ''
local sep1 = ' '
local sep2 = ' '
if parms.opt_adjectival and want_name then
sep1 = '-'
sep2 = '-'
end
if omitsep and sep == '' then
-- Testing the id of the most significant unit should be sufficient.
sep1 = ''
sep2 = ''
end
local parts = { first_unit.valinfo[1].show .. sep1 .. id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, unit.valinfo[1].show .. sep1 .. (make_id(parms, 1, unit)))
end
end
return table.concat(parts, sep2) .. mid
end
local add_unit = (parms.abbr == 'mos') or
parms[parms.opt_flip and 'out_range_x' or 'in_range_x'] or
(not want_name and parms.abbr_range_x)
local range = parms.range
if range and not add_unit then
unlink(first_unit)
end
local id = range and make_id(parms, range.n + 1, first_unit) or id1
local extra, was_hyphenated = hyphenated_maybe(parms, want_name, sep, id, 'in')
if was_hyphenated then
add_unit = false
end
local result
local valinfo = first_unit.valinfo
if range then
for i = 0, range.n do
local number_word
if i == range.n then
add_unit = false
number_word = true
end
decorate_value(parms, first_unit, i+1, number_word)
local show = valinfo[i+1].show
if add_unit then
show = show .. first_unit.sep .. (i == 0 and id1 or make_id(parms, i+1, first_unit))
end
if i == 0 then
result = show
else
result = range_text(range[i], want_name, parms, result, show, 'in')
end
end
else
decorate_value(parms, first_unit, 1, true)
result = valinfo[1].show
end
return result .. preunit .. extra
end
local function process_one_output(parms, out_current)
-- Processing required for each output unit.
-- Return block of text to represent output (value/unit).
local inout = out_current.inout -- normally 'out' but can be 'in' for order=out
local id1, want_name = make_id(parms, 1, out_current)
local sep = out_current.sep -- set by make_id
local preunit = parms.preunit2
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_output_unit_only then
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if out_current.builtin == 'mach' and out_current.sep ~= '' then -- '' means omitsep with non-enwiki name
local prefix = id1 .. ' '
local range = parms.range
local valinfo = out_current.valinfo
local result = prefix .. valinfo[1].show
if range then
-- For simplicity and because more not needed, handle one range item only.
result = range_text(range[1], want_name, parms, result, prefix .. valinfo[2].show, inout, {spaced=true})
end
return preunit .. result
end
local add_unit = (parms[parms.opt_flip and 'in_range_x' or 'out_range_x'] or
(not want_name and parms.abbr_range_x)) and
not parms.opt_output_number_only
local range = parms.range
if range and not add_unit then
unlink(out_current)
end
local id = range and make_id(parms, range.n + 1, out_current) or id1
local extra, was_hyphenated = hyphenated_maybe(parms, want_name, sep, id, inout)
if was_hyphenated then
add_unit = false
end
local result
local valinfo = out_current.valinfo
if range then
for i = 0, range.n do
local number_word
if i == range.n then
add_unit = false
number_word = true
end
decorate_value(parms, out_current, i+1, number_word)
local show = valinfo[i+1].show
if add_unit then
show = show .. out_current.sep .. (i == 0 and id1 or make_id(parms, i+1, out_current))
end
if i == 0 then
result = show
else
result = range_text(range[i], want_name, parms, result, show, inout)
end
end
else
decorate_value(parms, out_current, 1, true)
result = valinfo[1].show
end
if parms.opt_output_number_only then
return result
end
return result .. preunit .. extra
end
local function make_output_single(parms, in_unit_table, out_unit_table)
-- Return true, item where item = wikitext of the conversion result
-- for a single output (which is not a combination or a multiple);
-- or return false, t where t is an error message table.
if parms.opt_order_out and in_unit_table.unitcode == out_unit_table.unitcode then
out_unit_table.valinfo = in_unit_table.valinfo
else
out_unit_table.valinfo = collection()
for _, v in ipairs(in_unit_table.valinfo) do
local success, info = cvtround(parms, v, in_unit_table, out_unit_table)
if not success then return false, info end
out_unit_table.valinfo:add(info)
end
end
return true, process_one_output(parms, out_unit_table)
end
local function make_output_multiple(parms, in_unit_table, out_unit_table)
-- Return true, item where item = wikitext of the conversion result
-- for an output which is a multiple (like 'ftin');
-- or return false, t where t is an error message table.
local inout = out_unit_table.inout -- normally 'out' but can be 'in' for order=out
local multiple = out_unit_table.multiple -- table of scaling factors (will not be nil)
local combos = out_unit_table.combination -- table of unit tables (will not be nil)
local abbr = parms.abbr
local abbr_org = parms.abbr_org
local disp = parms.disp
local want_name = (abbr_org == nil and (disp == 'or' or disp == 'slash')) or
not (abbr == 'on' or abbr == inout or abbr == 'mos')
local want_link = (parms.lk == 'on' or parms.lk == inout)
local mid = parms.opt_flip and parms.mid or ''
local sep1 = ' '
local sep2 = ' '
if parms.opt_adjectival and want_name then
sep1 = '-'
sep2 = '-'
end
local do_spell = parms.opt_spell_out
parms.opt_spell_out = nil -- so the call to cvtround does not spell the value
local function make_result(info, isfirst)
local fmt, outvalue, sign
local results = {}
for i = 1, #combos do
local tfrac, thisvalue, strforce
local out_current = combos[i]
out_current.inout = inout
local scale = multiple[i]
if i == 1 then -- least significant unit ('in' from 'ftin')
local decimals
out_current.frac = out_unit_table.frac
local success, outinfo = cvtround(parms, info, in_unit_table, out_current)
if not success then return false, outinfo end
if isfirst then
out_unit_table.valinfo = { outinfo } -- in case output value of first least significant unit is needed
end
sign = outinfo.sign
tfrac = outinfo.fraction_table
if outinfo.is_scientific then
strforce = outinfo.show
decimals = ''
elseif tfrac then
decimals = ''
else
local show = outinfo.show -- number as a string in local language
local p1, p2 = show:find(numdot, 1, true)
decimals = p1 and show:sub(p2 + 1) or '' -- text after numdot, if any
end
fmt = '%.' .. ulen(decimals) .. 'f' -- to reproduce precision
if decimals == '' then
if tfrac then
outvalue = floor(outinfo.raw_absvalue) -- integer part only; fraction added later
else
outvalue = floor(outinfo.raw_absvalue + 0.5) -- keep all integer digits of least significant unit
end
else
outvalue = outinfo.absvalue
end
end
if scale then
outvalue, thisvalue = divide(outvalue, scale)
else
thisvalue = outvalue
end
local id
if want_name then
if varname then
local clean
if strforce or tfrac then
clean = '.1' -- dummy value to force name for floating point
else
clean = format(fmt, thisvalue)
end
id = variable_name(clean, out_current)
else
local key = 'name2'
if parms.opt_adjectival then
key = 'name1'
elseif tfrac then
if thisvalue == 0 then
key = 'name1'
end
elseif parms.opt_singular then
if 0 < thisvalue and thisvalue < 1.0001 then
key = 'name1'
end
else
if thisvalue == 1 then
key = 'name1'
end
end
id = out_current[key]
end
else
id = out_current['symbol']
end
if i == 1 and omit_separator(id) then
-- Testing the id of the least significant unit should be sufficient.
sep1 = ''
sep2 = ''
end
if want_link then
local link = out_current.link
if link then
id = make_link(link, id, out_current)
end
end
local strval
local spell_inout = (i == #combos or outvalue == 0) and inout or '' -- trick so the last value processed (first displayed) has uppercase, if requested
if strforce and outvalue == 0 then
sign = '' -- any sign is in strforce
strval = strforce -- show small values in scientific notation; will only use least significant unit
elseif tfrac then
local wholestr = (thisvalue > 0) and tostring(thisvalue) or nil
strval = format_fraction(parms, spell_inout, false, wholestr, tfrac.numstr, tfrac.denstr, do_spell)
else
strval = (thisvalue == 0) and from_en('0') or with_separator(parms, format(fmt, thisvalue))
if do_spell then
strval = spell_number(parms, spell_inout, strval) or strval
end
end
table.insert(results, strval .. sep1 .. id)
if outvalue == 0 then
break
end
fmt = '%.0f' -- only least significant unit can have a non-integral value
end
local reversed, count = {}, #results
for i = 1, count do
reversed[i] = results[count + 1 - i]
end
return true, sign .. table.concat(reversed, sep2)
end
local valinfo = in_unit_table.valinfo
local success, result = make_result(valinfo[1], true)
if not success then return false, result end
local range = parms.range
if range then
for i = 1, range.n do
local success, result2 = make_result(valinfo[i+1])
if not success then return false, result2 end
result = range_text(range[i], want_name, parms, result, result2, inout, {spaced=true})
end
end
return true, result .. mid
end
local function process(parms, in_unit_table, out_unit_table)
-- Return true, s, outunit where s = final wikitext result,
-- or return false, t where t is an error message table.
linked_pages = {}
local success, bad_output
local bad_input_mcode = in_unit_table.bad_mcode -- nil if input unit is a valid convert unit
local out_unit = parms.out_unit
if out_unit == nil or out_unit == '' or type(out_unit) == 'function' then
if bad_input_mcode or parms.opt_input_unit_only then
bad_output = ''
else
local getdef = type(out_unit) == 'function' and out_unit or get_default
success, out_unit = getdef(in_unit_table.valinfo[1].value, in_unit_table)
parms.out_unit = out_unit
if not success then
bad_output = out_unit
end
end
end
if not bad_output and not out_unit_table then
success, out_unit_table = lookup(parms, out_unit, 'any_combination')
if success then
local mismatch = check_mismatch(in_unit_table, out_unit_table)
if mismatch then
bad_output = mismatch
end
else
bad_output = out_unit_table
end
end
local lhs, rhs
local flipped = parms.opt_flip and not bad_input_mcode
if bad_output then
rhs = (bad_output == '') and '' or message(parms, bad_output)
elseif parms.opt_input_unit_only then
rhs = ''
else
local combos -- nil (for 'ft' or 'ftin'), or table of unit tables (for 'm ft')
if not out_unit_table.multiple then -- nil/false ('ft' or 'm ft'), or table of factors ('ftin')
combos = out_unit_table.combination
end
local frac = parms.frac -- nil or denominator of fraction for output values
if frac then
-- Apply fraction to the unit (if only one), or to non-SI units (if a combination),
-- except that if a precision is also specified, the fraction only applies to
-- the hand unit; that allows the following result:
-- {{convert|156|cm|in hand|1|frac=2}} → 156 centimetres (61.4 in; 15.1½ hands)
-- However, the following is handled elsewhere as a special case:
-- {{convert|156|cm|hand in|1|frac=2}} → 156 centimetres (15.1½ hands; 61½ in)
if combos then
local precision = parms.precision
for _, unit in ipairs(combos) do
if unit.builtin == 'hand' or (not precision and not unit.prefixes) then
unit.frac = frac
end
end
else
out_unit_table.frac = frac
end
end
local outputs = {}
local imax = combos and #combos or 1 -- 1 (single unit) or number of unit tables
if imax == 1 then
parms.opt_order_out = nil -- only useful with an output combination
end
if not flipped and not parms.opt_order_out then
-- Process left side first so any duplicate links (from lk=on) are suppressed
-- on right. Example: {{convert|28|e9pc|e9ly|abbr=off|lk=on}}
lhs = process_input(parms, in_unit_table)
end
for i = 1, imax do
local success, item
local out_current = combos and combos[i] or out_unit_table
out_current.inout = 'out'
if i == 1 then
if imax > 1 and out_current.builtin == 'hand' then
out_current.out_next = combos[2] -- built-in hand can influence next unit in a combination
end
if parms.opt_order_out then
out_current.inout = 'in'
end
end
if out_current.multiple then
success, item = make_output_multiple(parms, in_unit_table, out_current)
else
success, item = make_output_single(parms, in_unit_table, out_current)
end
if not success then return false, item end
outputs[i] = item
end
if parms.opt_order_out then
lhs = outputs[1]
table.remove(outputs, 1)
end
local sep = parms.table_joins and parms.table_joins[2] or parms.join_between
rhs = table.concat(outputs, sep)
end
if flipped or not lhs then
local input = process_input(parms, in_unit_table)
if flipped then
lhs = rhs
rhs = input
else
lhs = input
end
end
if parms.join_before then
lhs = parms.join_before .. lhs
end
local wikitext
if bad_input_mcode then
if bad_input_mcode == '' then
wikitext = lhs
else
wikitext = lhs .. message(parms, bad_input_mcode)
end
elseif parms.table_joins then
wikitext = parms.table_joins[1] .. lhs .. parms.table_joins[2] .. rhs
else
wikitext = lhs .. parms.joins[1] .. rhs .. parms.joins[2]
end
if parms.warnings and not bad_input_mcode then
wikitext = wikitext .. parms.warnings
end
return true, get_styles(parms) .. wikitext, out_unit_table
end
local function main_convert(frame)
-- Do convert, and if needed, do it again with higher default precision.
local parms = { frame = frame } -- will hold template arguments, after translation
set_config(frame.args)
local success, result = get_parms(parms, frame:getParent().args)
if success then
if type(result) ~= 'table' then
return tostring(result)
end
local in_unit_table = result
local out_unit_table
for _ = 1, 2 do -- use counter so cannot get stuck repeating convert
success, result, out_unit_table = process(parms, in_unit_table, out_unit_table)
if success and parms.do_convert_again then
parms.do_convert_again = false
else
break
end
end
end
-- If input=x gives a problem, the result should be just the user input
-- (if x is a property like P123 it has been replaced with '').
-- An unknown input unit would display the input and an error message
-- with success == true at this point.
-- Also, can have success == false with a message that outputs an empty string.
if parms.input_text then
if success and not parms.have_problem then
return result
end
local cat
if parms.tracking then
-- Add a tracking category using the given text as the category sort key.
-- There is currently only one type of tracking, but in principle multiple
-- items could be tracked, using different sort keys for convenience.
cat = wanted_category('tracking', parms.tracking)
end
return parms.input_text .. (cat or '')
end
return success and result or message(parms, result)
end
local function _unit(unitcode, options)
-- Helper function for Module:Val to look up a unit.
-- Parameter unitcode must be a string to identify the wanted unit.
-- Parameter options must be nil or a table with optional fields:
-- value = number (for sort key; default value is 1)
-- scaled_top = nil for a normal unit, or a number for a unit which is
-- the denominator of a per unit (for sort key)
-- si = { 'symbol', 'link' }
-- (a table with two strings) to make an SI unit
-- that will be used for the look up
-- link = true if result should be [[linked]]
-- sort = 'on' or 'debug' if result should include a sort key in a
-- span element ('debug' makes the key visible)
-- name = true for the name of the unit instead of the symbol
-- us = true for the US spelling of the unit, if any
-- Return nil if unitcode is not a non-empty string.
-- Otherwise return a table with fields:
-- text = requested symbol or name of unit, optionally linked
-- scaled_value = input value adjusted by unit scale; used for sort key
-- sortspan = span element with sort key like that provided by {{ntsh}},
-- calculated from the result of converting value
-- to a base unit with scale 1.
-- unknown = true if the unitcode was not known
unitcode = strip(unitcode)
if unitcode == nil or unitcode == '' then
return nil
end
set_config({})
linked_pages = {}
options = options or {}
local parms = {
abbr = options.name and 'off' or 'on',
lk = options.link and 'on' or nil,
opt_sp_us = options.us and true or nil,
opt_ignore_error = true, -- do not add pages using this function to 'what links here' for Module:Convert/extra
opt_sortable_on = options.sort == 'on' or options.sort == 'debug',
opt_sortable_debug = options.sort == 'debug',
}
if options.si then
-- Make a dummy table of units (just one unit) for lookup to use.
-- This makes lookup recognize any SI prefix in the unitcode.
local symbol = options.si[1] or '?'
parms.unittable = { [symbol] = {
_name1 = symbol,
_name2 = symbol,
_symbol = symbol,
utype = symbol,
scale = symbol == 'g' and 0.001 or 1,
prefixes = 1,
default = symbol,
link = options.si[2],
}}
end
local success, unit_table = lookup(parms, unitcode, 'no_combination')
if not success then
unit_table = setmetatable({
symbol = unitcode, name2 = unitcode, utype = unitcode,
scale = 1, default = '', defkey = '', linkey = '' }, unit_mt)
end
local value = tonumber(options.value) or 1
local clean = tostring(abs(value))
local info = {
value = value,
altvalue = value,
singular = (clean == '1'),
clean = clean,
show = clean,
}
unit_table.inout = 'in'
unit_table.valinfo = { info }
local sortspan, scaled_value
if options.sort then
sortspan, scaled_value = make_table_or_sort(parms, value, info, unit_table, options.scaled_top)
end
return {
text = make_id(parms, 1, unit_table),
sortspan = sortspan,
scaled_value = scaled_value,
unknown = not success and true or nil,
}
end
return { convert = main_convert, _unit = _unit }
da3d419635c73ffef0a5bcc2a7d6620979271521
Module:Convert/data
828
47
110
109
2022-09-04T15:24:31Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- Conversion data used by [[Module:Convert]] which uses mw.loadData() for
-- read-only access to this module so that it is loaded only once per page.
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
--
-- These data tables follow:
-- all_units all properties for a unit, including default output
-- default_exceptions exceptions for default output ('kg' and 'g' have different defaults)
-- link_exceptions exceptions for links ('kg' and 'g' have different links)
--
-- These tables are generated by a script which reads the wikitext of a page that
-- documents the required properties of each unit; see [[:en:Module:Convert/doc]].
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local all_units = {
["Gy"] = {
_name1 = "gray",
_symbol = "Gy",
utype = "absorbed radiation dose",
scale = 1,
prefixes = 1,
default = "rad",
link = "Gray (unit)",
},
["rad"] = {
_name1 = "rad",
_symbol = "rad",
utype = "absorbed radiation dose",
scale = 0.01,
prefixes = 1,
default = "Gy",
link = "Rad (unit)",
},
["cm/s2"] = {
name1 = "centimetre per second squared",
name1_us = "centimeter per second squared",
name2 = "centimetres per second squared",
name2_us = "centimeters per second squared",
symbol = "cm/s<sup>2</sup>",
utype = "acceleration",
scale = 0.01,
default = "ft/s2",
link = "Gal (unit)",
},
["ft/s2"] = {
name1 = "foot per second squared",
name2 = "feet per second squared",
symbol = "ft/s<sup>2</sup>",
utype = "acceleration",
scale = 0.3048,
default = "m/s2",
},
["g0"] = {
name1 = "standard gravity",
name2 = "standard gravities",
symbol = "''g''<sub>0</sub>",
utype = "acceleration",
scale = 9.80665,
default = "m/s2",
},
["g-force"] = {
name2 = "''g''",
symbol = "''g''",
utype = "acceleration",
scale = 9.80665,
default = "m/s2",
link = "g-force",
},
["km/hs"] = {
name1 = "kilometre per hour per second",
name1_us = "kilometer per hour per second",
name2 = "kilometres per hour per second",
name2_us = "kilometers per hour per second",
symbol = "km/(h⋅s)",
utype = "acceleration",
scale = 0.27777777777777779,
default = "mph/s",
link = "Acceleration",
},
["km/s2"] = {
name1 = "kilometre per second squared",
name1_us = "kilometer per second squared",
name2 = "kilometres per second squared",
name2_us = "kilometers per second squared",
symbol = "km/s<sup>2</sup>",
utype = "acceleration",
scale = 1000,
default = "mph/s",
link = "Acceleration",
},
["m/s2"] = {
name1 = "metre per second squared",
name1_us = "meter per second squared",
name2 = "metres per second squared",
name2_us = "meters per second squared",
symbol = "m/s<sup>2</sup>",
utype = "acceleration",
scale = 1,
default = "ft/s2",
},
["mph/s"] = {
name1 = "mile per hour per second",
name2 = "miles per hour per second",
symbol = "mph/s",
utype = "acceleration",
scale = 0.44704,
default = "km/hs",
link = "Acceleration",
},
["km/h/s"] = {
target = "km/hs",
},
["standard gravity"] = {
target = "g0",
},
["1000sqft"] = {
name1 = "thousand square feet",
name2 = "thousand square feet",
symbol = "1000 sq ft",
utype = "area",
scale = 92.90304,
default = "m2",
link = "Square foot",
},
["a"] = {
_name1 = "are",
_symbol = "a",
utype = "area",
scale = 100,
prefixes = 1,
default = "sqft",
link = "Hectare#Are",
},
["acre"] = {
symbol = "acre",
usename = 1,
utype = "area",
scale = 4046.8564224,
default = "ha",
subdivs = { ["rood"] = { 4, default = "ha" }, ["sqperch"] = { 160, default = "ha" } },
},
["acre-sing"] = {
target = "acre",
},
["arpent"] = {
symbol = "arpent",
usename = 1,
utype = "area",
scale = 3418.89,
default = "ha",
},
["cda"] = {
name1 = "cuerda",
symbol = "cda",
utype = "area",
scale = 3930.395625,
default = "ha acre",
},
["daa"] = {
name1 = "decare",
symbol = "daa",
utype = "area",
scale = 1000,
default = "km2 sqmi",
},
["dunam"] = {
symbol = "dunam",
usename = 1,
utype = "area",
scale = 1000,
default = "km2 sqmi",
},
["dunum"] = {
symbol = "dunum",
usename = 1,
utype = "area",
scale = 1000,
default = "km2 sqmi",
link = "Dunam",
},
["ha"] = {
name1 = "hectare",
symbol = "ha",
utype = "area",
scale = 10000,
default = "acre",
},
["hectare"] = {
name1 = "hectare",
symbol = "ha",
usename = 1,
utype = "area",
scale = 10000,
default = "acre",
},
["Irish acre"] = {
name1 = "Irish acre",
symbol = "Irish acres",
utype = "area",
scale = 6555.2385024,
default = "ha",
link = "Acre (Irish)",
},
["m2"] = {
_name1 = "square metre",
_name1_us= "square meter",
_symbol = "m<sup>2</sup>",
prefix_position= 8,
utype = "area",
scale = 1,
prefixes = 2,
default = "sqft",
link = "Square metre",
},
["pondemaat"] = {
name1 = "pondemaat",
name2 = "pondemaat",
symbol = "pond",
utype = "area",
scale = 3674.363358816,
default = "m2",
link = ":nl:pondemaat",
},
["pyeong"] = {
name2 = "pyeong",
symbol = "pyeong",
usename = 1,
utype = "area",
scale = 3.3057851239669422,
default = "m2",
},
["rai"] = {
name2 = "rai",
symbol = "rai",
utype = "area",
scale = 1600,
default = "m2",
link = "Rai (unit)",
},
["rood"] = {
symbol = "rood",
usename = 1,
utype = "area",
scale = 1011.7141056,
default = "sqft m2",
subdivs = { ["sqperch"] = { 40, default = "m2" } },
link = "Rood (unit)",
},
["sqfoot"] = {
name1 = "square foot",
name2 = "square foot",
symbol = "sq ft",
utype = "area",
scale = 0.09290304,
default = "m2",
},
["sqft"] = {
name1 = "square foot",
name2 = "square feet",
symbol = "sq ft",
utype = "area",
scale = 0.09290304,
default = "m2",
},
["sqin"] = {
name1 = "square inch",
name2 = "square inches",
symbol = "sq in",
utype = "area",
scale = 0.00064516,
default = "cm2",
},
["sqmi"] = {
name1 = "square mile",
symbol = "sq mi",
utype = "area",
scale = 2589988.110336,
default = "km2",
},
["sqnmi"] = {
name1 = "square nautical mile",
symbol = "sq nmi",
utype = "area",
scale = 3429904,
default = "km2 sqmi",
link = "Nautical mile",
},
["sqperch"] = {
name2 = "perches",
symbol = "perch",
usename = 1,
utype = "area",
scale = 25.29285264,
default = "m2",
link = "Rod (unit)#Area and volume",
},
["sqverst"] = {
symbol = "square verst",
usename = 1,
utype = "area",
scale = 1138062.24,
default = "km2 sqmi",
link = "Verst",
},
["sqyd"] = {
name1 = "square yard",
symbol = "sq yd",
utype = "area",
scale = 0.83612736,
default = "m2",
},
["tsubo"] = {
name2 = "tsubo",
symbol = "tsubo",
usename = 1,
utype = "area",
scale = 3.3057851239669422,
default = "m2",
link = "Japanese units of measurement#Area",
},
["acres"] = {
target = "acre",
},
["are"] = {
target = "a",
},
["decare"] = {
target = "daa",
},
["foot2"] = {
target = "sqfoot",
},
["ft2"] = {
target = "sqft",
},
["in2"] = {
target = "sqin",
symbol = "in<sup>2</sup>",
},
["km²"] = {
target = "km2",
},
["mi2"] = {
target = "sqmi",
},
["million acre"] = {
target = "e6acre",
},
["million acres"] = {
target = "e6acre",
},
["million hectares"] = {
target = "e6ha",
},
["m²"] = {
target = "m2",
},
["nmi2"] = {
target = "sqnmi",
},
["pond"] = {
target = "pondemaat",
},
["sq arp"] = {
target = "arpent",
},
["sqkm"] = {
target = "km2",
},
["sqm"] = {
target = "m2",
},
["square verst"] = {
target = "sqverst",
},
["verst2"] = {
target = "sqverst",
},
["yd2"] = {
target = "sqyd",
},
["m2/ha"] = {
name1 = "square metre per hectare",
name1_us = "square meter per hectare",
name2 = "square metres per hectare",
name2_us = "square meters per hectare",
symbol = "m<sup>2</sup>/ha",
utype = "area per unit area",
scale = 0.0001,
default = "sqft/acre",
link = "Basal area",
},
["sqft/acre"] = {
name1 = "square foot per acre",
name2 = "square feet per acre",
symbol = "sq ft/acre",
utype = "area per unit area",
scale = 2.295684113865932e-5,
default = "m2/ha",
link = "Basal area",
},
["cent"] = {
name1 = "cent",
symbol = "¢",
utype = "cent",
scale = 1,
default = "cent",
link = "Cent (currency)",
},
["¢"] = {
target = "cent",
},
["A.h"] = {
name1 = "ampere hour",
symbol = "A⋅h",
utype = "charge",
scale = 3600,
default = "coulomb",
},
["coulomb"] = {
_name1 = "coulomb",
_symbol = "C",
utype = "charge",
scale = 1,
prefixes = 1,
default = "e",
link = "Coulomb",
},
["e"] = {
name1 = "elementary charge",
symbol = "''e''",
utype = "charge",
scale = 1.602176487e-19,
default = "coulomb",
},
["g-mol"] = {
name1 = "gram-mole",
symbol = "g‑mol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["gmol"] = {
name1 = "gram-mole",
symbol = "gmol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["kmol"] = {
name1 = "kilomole",
symbol = "kmol",
utype = "chemical amount",
scale = 1000,
default = "lbmol",
link = "Mole (unit)",
},
["lb-mol"] = {
name1 = "pound-mole",
symbol = "lb‑mol",
utype = "chemical amount",
scale = 453.59237,
default = "mol",
},
["lbmol"] = {
name1 = "pound-mole",
symbol = "lbmol",
utype = "chemical amount",
scale = 453.59237,
default = "mol",
},
["mol"] = {
name1 = "mole",
symbol = "mol",
utype = "chemical amount",
scale = 1,
default = "lbmol",
link = "Mole (unit)",
},
["kgCO2/L"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg(CO<sub>2</sub>)/L",
utype = "co2 per unit volume",
scale = 1000,
default = "lbCO2/USgal",
link = "Exhaust gas",
},
["lbCO2/USgal"] = {
name1 = "pound per US gallon",
name2 = "pounds per US gallon",
symbol = "lbCO2/US gal",
utype = "co2 per unit volume",
scale = 119.82642731689663,
default = "kgCO2/L",
link = "Exhaust gas",
},
["oz/lb"] = {
per = { "oz", "lb" },
utype = "concentration",
default = "mg/kg",
},
["mg/kg"] = {
per = { "mg", "kg" },
utype = "concentration",
default = "oz/lb",
},
["g/dm3"] = {
name1 = "gram per cubic decimetre",
name1_us = "gram per cubic decimeter",
name2 = "grams per cubic decimetre",
name2_us = "grams per cubic decimeter",
symbol = "g/dm<sup>3</sup>",
utype = "density",
scale = 1,
default = "kg/m3",
link = "Density",
},
["g/L"] = {
name1 = "gram per litre",
name1_us = "gram per liter",
name2 = "grams per litre",
name2_us = "grams per liter",
symbol = "g/L",
utype = "density",
scale = 1,
default = "lb/cuin",
link = "Density",
},
["g/mL"] = {
name1 = "gram per millilitre",
name1_us = "gram per milliliter",
name2 = "grams per millilitre",
name2_us = "grams per milliliter",
symbol = "g/mL",
utype = "density",
scale = 1000,
default = "lb/cuin",
link = "Density",
},
["g/ml"] = {
name1 = "gram per millilitre",
name1_us = "gram per milliliter",
name2 = "grams per millilitre",
name2_us = "grams per milliliter",
symbol = "g/ml",
utype = "density",
scale = 1000,
default = "lb/cuin",
link = "Density",
},
["kg/dm3"] = {
name1 = "kilogram per cubic decimetre",
name1_us = "kilogram per cubic decimeter",
name2 = "kilograms per cubic decimetre",
name2_us = "kilograms per cubic decimeter",
symbol = "kg/dm<sup>3</sup>",
utype = "density",
scale = 1000,
default = "lb/cuft",
link = "Density",
},
["kg/L"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg/L",
utype = "density",
scale = 1000,
default = "lb/USgal",
link = "Density",
},
["kg/l"] = {
name1 = "kilogram per litre",
name1_us = "kilogram per liter",
name2 = "kilograms per litre",
name2_us = "kilograms per liter",
symbol = "kg/l",
utype = "density",
scale = 1000,
default = "lb/USgal",
link = "Density",
},
["kg/m3"] = {
name1 = "kilogram per cubic metre",
name1_us = "kilogram per cubic meter",
name2 = "kilograms per cubic metre",
name2_us = "kilograms per cubic meter",
symbol = "kg/m<sup>3</sup>",
utype = "density",
scale = 1,
default = "lb/cuyd",
link = "Density",
},
["lb/cuft"] = {
name1 = "pound per cubic foot",
name2 = "pounds per cubic foot",
symbol = "lb/cu ft",
utype = "density",
scale = 16.018463373960142,
default = "g/cm3",
link = "Density",
},
["lb/cuin"] = {
name1 = "pound per cubic inch",
name2 = "pounds per cubic inch",
symbol = "lb/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["lb/cuyd"] = {
name1 = "pound per cubic yard",
name2 = "pounds per cubic yard",
symbol = "lb/cu yd",
utype = "density",
scale = 0.5932764212577829,
default = "kg/m3",
link = "Density",
},
["lb/impgal"] = {
name1 = "pound per imperial gallon",
name2 = "pounds per imperial gallon",
symbol = "lb/imp gal",
utype = "density",
scale = 99.776372663101697,
default = "kg/L",
link = "Density",
},
["lb/in3"] = {
name1 = "pound per cubic inch",
name2 = "pounds per cubic inch",
symbol = "lb/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["lb/U.S.gal"] = {
name1 = "pound per U.S. gallon",
name2 = "pounds per U.S. gallon",
symbol = "lb/U.S. gal",
utype = "density",
scale = 119.82642731689663,
default = "kg/L",
link = "Density",
},
["lb/USbu"] = {
name1 = "pound per US bushel",
name2 = "pounds per US bushel",
symbol = "lb/US bu",
utype = "density",
scale = 12.871859780974471,
default = "kg/m3",
link = "Bushel",
},
["lb/USgal"] = {
name1 = "pound per US gallon",
name2 = "pounds per US gallon",
symbol = "lb/US gal",
utype = "density",
scale = 119.82642731689663,
default = "kg/L",
link = "Density",
},
["lbm/cuin"] = {
name1 = "pound mass per cubic inch",
name2 = "pounds mass per cubic inch",
symbol = "lbm/cu in",
utype = "density",
scale = 27679.904710203122,
default = "g/cm3",
link = "Density",
},
["mg/L"] = {
name1 = "milligram per litre",
name1_us = "milligram per liter",
name2 = "milligrams per litre",
name2_us = "milligrams per liter",
symbol = "mg/L",
utype = "density",
scale = 0.001,
default = "lb/cuin",
link = "Density",
},
["oz/cuin"] = {
name1 = "ounce per cubic inch",
name2 = "ounces per cubic inch",
symbol = "oz/cu in",
utype = "density",
scale = 1729.9940443876951,
default = "g/cm3",
link = "Density",
},
["g/cm3"] = {
per = { "g", "cm3" },
utype = "density",
default = "lb/cuin",
},
["g/m3"] = {
per = { "g", "m3" },
utype = "density",
default = "lb/cuyd",
link = "Density",
},
["Mg/m3"] = {
per = { "Mg", "m3" },
utype = "density",
default = "lb/cuft",
},
["mg/l"] = {
per = { "mg", "l" },
utype = "density",
default = "oz/cuin",
},
["μg/dL"] = {
per = { "μg", "dL" },
utype = "density",
default = "lb/cuin",
},
["μg/l"] = {
per = { "μg", "l" },
utype = "density",
default = "oz/cuin",
},
["lb/ft3"] = {
target = "lb/cuft",
},
["lb/yd3"] = {
target = "lb/cuyd",
},
["lbm/in3"] = {
target = "lbm/cuin",
},
["mcg/dL"] = {
target = "μg/dL",
},
["oz/in3"] = {
target = "oz/cuin",
},
["ug/dL"] = {
target = "μg/dL",
},
["ug/l"] = {
target = "μg/l",
},
["B.O.T.U."] = {
name1 = "Board of Trade Unit",
symbol = "B.O.T.U.",
utype = "energy",
scale = 3600000,
default = "MJ",
link = "Kilowatt-hour",
},
["bboe"] = {
name1 = "barrel of oil equivalent",
name2 = "barrels of oil equivalent",
symbol = "bboe",
utype = "energy",
scale = 6117863200,
default = "GJ",
},
["BOE"] = {
name1 = "barrel of oil equivalent",
name2 = "barrels of oil equivalent",
symbol = "BOE",
utype = "energy",
scale = 6117863200,
default = "GJ",
},
["BTU"] = {
name1 = "British thermal unit",
symbol = "BTU",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
},
["Btu"] = {
name1 = "British thermal unit",
symbol = "Btu",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
},
["BTU-39F"] = {
name1 = "British thermal unit (39°F)",
name2 = "British thermal units (39°F)",
symbol = "BTU<sub>39°F</sub>",
utype = "energy",
scale = 1059.67,
default = "kJ",
link = "British thermal unit",
},
["Btu-39F"] = {
name1 = "British thermal unit (39°F)",
name2 = "British thermal units (39°F)",
symbol = "Btu<sub>39°F</sub>",
utype = "energy",
scale = 1059.67,
default = "kJ",
link = "British thermal unit",
},
["BTU-59F"] = {
name1 = "British thermal unit (59°F)",
name2 = "British thermal units (59°F)",
symbol = "BTU<sub>59°F</sub>",
utype = "energy",
scale = 1054.804,
default = "kJ",
link = "British thermal unit",
},
["Btu-59F"] = {
name1 = "British thermal unit (59°F)",
name2 = "British thermal units (59°F)",
symbol = "Btu<sub>59°F</sub>",
utype = "energy",
scale = 1054.804,
default = "kJ",
link = "British thermal unit",
},
["BTU-60F"] = {
name1 = "British thermal unit (60°F)",
name2 = "British thermal units (60°F)",
symbol = "BTU<sub>60°F</sub>",
utype = "energy",
scale = 1054.68,
default = "kJ",
link = "British thermal unit",
},
["Btu-60F"] = {
name1 = "British thermal unit (60°F)",
name2 = "British thermal units (60°F)",
symbol = "Btu<sub>60°F</sub>",
utype = "energy",
scale = 1054.68,
default = "kJ",
link = "British thermal unit",
},
["BTU-63F"] = {
name1 = "British thermal unit (63°F)",
name2 = "British thermal units (63°F)",
symbol = "BTU<sub>63°F</sub>",
utype = "energy",
scale = 1054.6,
default = "kJ",
link = "British thermal unit",
},
["Btu-63F"] = {
name1 = "British thermal unit (63°F)",
name2 = "British thermal units (63°F)",
symbol = "Btu<sub>63°F</sub>",
utype = "energy",
scale = 1054.6,
default = "kJ",
link = "British thermal unit",
},
["BTU-ISO"] = {
name1 = "British thermal unit (ISO)",
name2 = "British thermal units (ISO)",
symbol = "BTU<sub>ISO</sub>",
utype = "energy",
scale = 1055.056,
default = "kJ",
link = "British thermal unit",
},
["Btu-ISO"] = {
target = "BTU-ISO",
},
["BTU-IT"] = {
name1 = "British thermal unit (IT)",
name2 = "British thermal units (IT)",
symbol = "BTU<sub>IT</sub>",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
link = "British thermal unit",
},
["Btu-IT"] = {
name1 = "British thermal unit (IT)",
name2 = "British thermal units (IT)",
symbol = "Btu<sub>IT</sub>",
utype = "energy",
scale = 1055.05585262,
default = "kJ",
link = "British thermal unit",
},
["BTU-mean"] = {
name1 = "British thermal unit (mean)",
name2 = "British thermal units (mean)",
symbol = "BTU<sub>mean</sub>",
utype = "energy",
scale = 1055.87,
default = "kJ",
link = "British thermal unit",
},
["Btu-mean"] = {
name1 = "British thermal unit (mean)",
name2 = "British thermal units (mean)",
symbol = "Btu<sub>mean</sub>",
utype = "energy",
scale = 1055.87,
default = "kJ",
link = "British thermal unit",
},
["BTU-th"] = {
name1 = "British thermal unit (thermochemical)",
name2 = "British thermal units (thermochemical)",
symbol = "BTU<sub>th</sub>",
utype = "energy",
scale = 1054.35026444,
default = "kJ",
link = "British thermal unit",
},
["Btu-th"] = {
name1 = "British thermal unit (thermochemical)",
name2 = "British thermal units (thermochemical)",
symbol = "Btu<sub>th</sub>",
utype = "energy",
scale = 1054.35026444,
default = "kJ",
link = "British thermal unit",
},
["Cal"] = {
name1 = "calorie",
symbol = "Cal",
utype = "energy",
scale = 4184,
default = "kJ",
},
["cal"] = {
name1 = "calorie",
symbol = "cal",
utype = "energy",
scale = 4.184,
default = "J",
},
["Cal-15"] = {
name1 = "Calorie (15°C)",
name2 = "Calories (15°C)",
symbol = "Cal<sub>15</sub>",
utype = "energy",
scale = 4185.8,
default = "kJ",
link = "Calorie",
},
["cal-15"] = {
name1 = "calorie (15°C)",
name2 = "calories (15°C)",
symbol = "cal<sub>15</sub>",
utype = "energy",
scale = 4.1858,
default = "J",
link = "Calorie",
},
["Cal-IT"] = {
name1 = "Calorie (International Steam Table)",
name2 = "Calories (International Steam Table)",
symbol = "Cal<sub>IT</sub>",
utype = "energy",
scale = 4186.8,
default = "kJ",
link = "Calorie",
},
["cal-IT"] = {
name1 = "calorie (International Steam Table)",
name2 = "calories (International Steam Table)",
symbol = "cal<sub>IT</sub>",
utype = "energy",
scale = 4.1868,
default = "J",
link = "Calorie",
},
["Cal-th"] = {
name1 = "Calorie (thermochemical)",
name2 = "Calories (thermochemical)",
symbol = "Cal<sub>th</sub>",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["cal-th"] = {
name1 = "calorie (thermochemical)",
name2 = "calories (thermochemical)",
symbol = "cal<sub>th</sub>",
utype = "energy",
scale = 4.184,
default = "J",
link = "Calorie",
},
["CHU-IT"] = {
name1 = "Celsius heat unit (International Table)",
name2 = "Celsius heat units (International Table)",
symbol = "CHU<sub>IT</sub>",
utype = "energy",
scale = 1899.100534716,
default = "kJ",
link = "Conversion of units#Energy",
},
["cufootnaturalgas"] = {
name1 = "cubic foot of natural gas",
name2 = "cubic foot of natural gas",
symbol = "cuftnaturalgas",
usename = 1,
utype = "energy",
scale = 1055055.85262,
default = "MJ",
link = "Conversion of units#Energy",
},
["cuftnaturalgas"] = {
name1 = "cubic foot of natural gas",
name2 = "cubic feet of natural gas",
symbol = "cuftnaturalgas",
usename = 1,
utype = "energy",
scale = 1055055.85262,
default = "MJ",
link = "Conversion of units#Energy",
},
["Eh"] = {
name1 = "Hartree",
symbol = "''E''<sub>h</sub>",
utype = "energy",
scale = 4.35974417e-18,
default = "eV",
},
["erg"] = {
symbol = "erg",
utype = "energy",
scale = 0.0000001,
default = "μJ",
},
["eV"] = {
name1 = "electronvolt",
symbol = "eV",
utype = "energy",
scale = 1.602176487e-19,
default = "aJ",
},
["feV"] = {
name1 = "femtoelectronvolt",
symbol = "feV",
utype = "energy",
scale = 1.602176487e-34,
default = "yJ",
link = "Electronvolt",
},
["foe"] = {
symbol = "foe",
utype = "energy",
scale = 1e44,
default = "YJ",
link = "Foe (unit)",
},
["ftlb"] = {
name1 = "foot-pound",
symbol = "ft⋅lb",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftlb-f"] = {
name1 = "foot-pound force",
name2 = "foot-pounds force",
symbol = "ft⋅lb<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftlbf"] = {
name1 = "foot-pound force",
name2 = "foot-pounds force",
symbol = "ft⋅lbf",
utype = "energy",
alttype = "torque",
scale = 1.3558179483314004,
default = "J",
link = "Foot-pound (energy)",
},
["ftpdl"] = {
name1 = "foot-poundal",
symbol = "ft⋅pdl",
utype = "energy",
scale = 0.0421401100938048,
default = "J",
},
["GeV"] = {
name1 = "gigaelectronvolt",
symbol = "GeV",
utype = "energy",
scale = 1.602176487e-10,
default = "nJ",
link = "Electronvolt",
},
["gTNT"] = {
name2 = "grams of TNT",
symbol = "gram of TNT",
usename = 1,
utype = "energy",
scale = 4184,
default = "kJ",
link = "TNT equivalent",
},
["Gtoe"] = {
name1 = "gigatonne of oil equivalent",
name2 = "gigatonnes of oil equivalent",
symbol = "Gtoe",
utype = "energy",
scale = 4.1868e19,
default = "EJ",
link = "Tonne of oil equivalent",
},
["GtonTNT"] = {
name2 = "gigatons of TNT",
symbol = "gigaton of TNT",
usename = 1,
utype = "energy",
scale = 4.184e18,
default = "EJ",
link = "TNT equivalent",
},
["GtTNT"] = {
name2 = "gigatonnes of TNT",
symbol = "gigatonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e18,
default = "EJ",
link = "TNT equivalent",
},
["GW.h"] = {
name1 = "gigawatt-hour",
symbol = "GW⋅h",
utype = "energy",
scale = 3.6e12,
default = "TJ",
link = "Kilowatt-hour",
},
["GWh"] = {
name1 = "gigawatt-hour",
symbol = "GWh",
utype = "energy",
scale = 3.6e12,
default = "TJ",
link = "Kilowatt-hour",
},
["hph"] = {
name1 = "horsepower-hour",
symbol = "hp⋅h",
utype = "energy",
scale = 2684519.537696172792,
default = "kWh",
link = "Horsepower",
},
["inlb"] = {
name1 = "inch-pound",
symbol = "in⋅lb",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inlb-f"] = {
name1 = "inch-pound force",
name2 = "inch-pounds force",
symbol = "in⋅lb<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inlbf"] = {
name1 = "inch-pound force",
name2 = "inch-pounds force",
symbol = "in⋅lbf",
utype = "energy",
alttype = "torque",
scale = 0.1129848290276167,
default = "mJ",
link = "Foot-pound (energy)",
},
["inoz-f"] = {
name1 = "inch-ounce force",
name2 = "inch-ounces force",
symbol = "in⋅oz<sub>f</sub>",
utype = "energy",
alttype = "torque",
scale = 0.00706155181422604375,
default = "mJ",
link = "Foot-pound (energy)",
},
["inozf"] = {
name1 = "inch-ounce force",
name2 = "inch-ounces force",
symbol = "in⋅ozf",
utype = "energy",
alttype = "torque",
scale = 0.00706155181422604375,
default = "mJ",
link = "Foot-pound (energy)",
},
["J"] = {
_name1 = "joule",
_symbol = "J",
utype = "energy",
scale = 1,
prefixes = 1,
default = "cal",
link = "Joule",
},
["kBOE"] = {
name1 = "kilo barrel of oil equivalent",
name2 = "kilo barrels of oil equivalent",
symbol = "kBOE",
utype = "energy",
scale = 6.1178632e12,
default = "TJ",
link = "Barrel of oil equivalent",
},
["kcal"] = {
name1 = "kilocalorie",
symbol = "kcal",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["kcal-15"] = {
name1 = "kilocalorie (15°C)",
name2 = "kilocalories (15°C)",
symbol = "kcal<sub>15</sub>",
utype = "energy",
scale = 4185.8,
default = "kJ",
link = "Calorie",
},
["kcal-IT"] = {
name1 = "kilocalorie (International Steam Table)",
name2 = "kilocalories (International Steam Table)",
symbol = "kcal<sub>IT</sub>",
utype = "energy",
scale = 4186.8,
default = "kJ",
link = "Calorie",
},
["kcal-th"] = {
name1 = "kilocalorie (thermochemical)",
name2 = "kilocalories (thermochemical)",
symbol = "kcal<sub>th</sub>",
utype = "energy",
scale = 4184,
default = "kJ",
link = "Calorie",
},
["kerg"] = {
name1 = "kiloerg",
symbol = "kerg",
utype = "energy",
scale = 0.0001,
default = "mJ",
link = "Erg",
},
["keV"] = {
name1 = "kiloelectronvolt",
symbol = "keV",
utype = "energy",
scale = 1.602176487e-16,
default = "fJ",
link = "Electronvolt",
},
["kgTNT"] = {
name2 = "kilograms of TNT",
symbol = "kilogram of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["kt(TNT)"] = {
name1 = "kilotonne",
name1_us = "kiloton",
symbol = "kt",
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["ktoe"] = {
name1 = "kilotonne of oil equivalent",
name2 = "kilotonnes of oil equivalent",
symbol = "ktoe",
utype = "energy",
scale = 4.1868e13,
default = "TJ",
link = "Tonne of oil equivalent",
},
["ktonTNT"] = {
name1 = "kiloton of TNT",
name2 = "kilotons of TNT",
symbol = "kt",
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["ktTNT"] = {
name2 = "kilotonnes of TNT",
symbol = "kilotonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e12,
default = "TJ",
link = "TNT equivalent",
},
["kW.h"] = {
name1 = "kilowatt-hour",
symbol = "kW⋅h",
utype = "energy",
scale = 3600000,
default = "MJ",
},
["kWh"] = {
name1 = "kilowatt-hour",
symbol = "kWh",
utype = "energy",
scale = 3600000,
default = "MJ",
},
["Mcal"] = {
name1 = "megacalorie",
symbol = "Mcal",
utype = "energy",
scale = 4184000,
default = "MJ",
link = "Calorie",
},
["mcal"] = {
name1 = "millicalorie",
symbol = "mcal",
utype = "energy",
scale = 0.004184,
default = "mJ",
link = "Calorie",
},
["Mcal-15"] = {
name1 = "megacalorie (15°C)",
name2 = "megacalories (15°C)",
symbol = "Mcal<sub>15</sub>",
utype = "energy",
scale = 4185800,
default = "MJ",
link = "Calorie",
},
["mcal-15"] = {
name1 = "millicalorie (15°C)",
name2 = "millicalories (15°C)",
symbol = "mcal<sub>15</sub>",
utype = "energy",
scale = 0.0041858,
default = "mJ",
link = "Calorie",
},
["Mcal-IT"] = {
name1 = "megacalorie (International Steam Table)",
name2 = "megacalories (International Steam Table)",
symbol = "Mcal<sub>IT</sub>",
utype = "energy",
scale = 4186800,
default = "MJ",
link = "Calorie",
},
["mcal-IT"] = {
name1 = "millicalorie (International Steam Table)",
name2 = "millicalories (International Steam Table)",
symbol = "mcal<sub>IT</sub>",
utype = "energy",
scale = 0.0041868,
default = "mJ",
link = "Calorie",
},
["Mcal-th"] = {
name1 = "megacalorie (thermochemical)",
name2 = "megacalories (thermochemical)",
symbol = "Mcal<sub>th</sub>",
utype = "energy",
scale = 4184000,
default = "MJ",
link = "Calorie",
},
["mcal-th"] = {
name1 = "millicalorie (thermochemical)",
name2 = "millicalories (thermochemical)",
symbol = "mcal<sub>th</sub>",
utype = "energy",
scale = 0.004184,
default = "mJ",
link = "Calorie",
},
["Merg"] = {
name1 = "megaerg",
symbol = "Merg",
utype = "energy",
scale = 0.1,
default = "J",
link = "Erg",
},
["merg"] = {
name1 = "millierg",
symbol = "merg",
utype = "energy",
scale = 0.0000000001,
default = "μJ",
link = "Erg",
},
["MeV"] = {
name1 = "megaelectronvolt",
symbol = "MeV",
utype = "energy",
scale = 1.602176487e-13,
default = "pJ",
link = "Electronvolt",
},
["meV"] = {
name1 = "millielectronvolt",
symbol = "meV",
utype = "energy",
scale = 1.602176487e-22,
default = "zJ",
link = "Electronvolt",
},
["MMBtu"] = {
name1 = "million British thermal units",
name2 = "million British thermal units",
symbol = "MMBtu",
utype = "energy",
scale = 1055055852.62,
default = "GJ",
link = "British thermal unit",
},
["Mt(TNT)"] = {
name1 = "megatonne",
name1_us = "megaton",
symbol = "Mt",
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["Mtoe"] = {
name1 = "megatonne of oil equivalent",
name2 = "megatonnes of oil equivalent",
symbol = "Mtoe",
utype = "energy",
scale = 4.1868e16,
default = "PJ",
link = "Tonne of oil equivalent",
},
["MtonTNT"] = {
name1 = "megaton of TNT",
name2 = "megatons of TNT",
symbol = "Mt",
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["mtonTNT"] = {
name2 = "millitons of TNT",
symbol = "milliton of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["MtTNT"] = {
name2 = "megatonnes of TNT",
symbol = "megatonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e15,
default = "PJ",
link = "TNT equivalent",
},
["mtTNT"] = {
name2 = "millitonnes of TNT",
symbol = "millitonne of TNT",
usename = 1,
utype = "energy",
scale = 4184000,
default = "MJ",
link = "TNT equivalent",
},
["MW.h"] = {
name1 = "megawatt-hour",
symbol = "MW⋅h",
utype = "energy",
scale = 3600000000,
default = "GJ",
link = "Kilowatt-hour",
},
["mW.h"] = {
name1 = "milliwatt-hour",
symbol = "mW⋅h",
utype = "energy",
scale = 3.6,
default = "J",
link = "Kilowatt-hour",
},
["MWh"] = {
name1 = "megawatt-hour",
symbol = "MWh",
utype = "energy",
scale = 3600000000,
default = "GJ",
link = "Kilowatt-hour",
},
["mWh"] = {
name1 = "milliwatt-hour",
symbol = "mWh",
utype = "energy",
scale = 3.6,
default = "J",
link = "Kilowatt-hour",
},
["neV"] = {
name1 = "nanoelectronvolt",
symbol = "neV",
utype = "energy",
scale = 1.602176487e-28,
default = "yJ",
link = "Electronvolt",
},
["PeV"] = {
name1 = "petaelectronvolt",
symbol = "PeV",
utype = "energy",
scale = 0.0001602176487,
default = "mJ",
link = "Electronvolt",
},
["peV"] = {
name1 = "picoelectronvolt",
symbol = "peV",
utype = "energy",
scale = 1.602176487e-31,
default = "yJ",
link = "Electronvolt",
},
["PSh"] = {
name1 = "Pferdestärkenstunde",
symbol = "PSh",
utype = "energy",
scale = 2647795.5,
default = "kWh",
},
["quad"] = {
name1 = "quadrillion British thermal units",
name2 = "quadrillion British thermal units",
symbol = "quad",
utype = "energy",
scale = 1.054804e18,
default = "EJ",
link = "Quad (unit)",
},
["Ry"] = {
name1 = "rydberg",
symbol = "Ry",
utype = "energy",
scale = 2.1798741e-18,
default = "eV",
link = "Rydberg constant",
},
["scf"] = {
name1 = "standard cubic foot",
name2 = "standard cubic feet",
symbol = "scf",
utype = "energy",
scale = 2869.2044809344,
default = "kJ",
},
["scfoot"] = {
name1 = "standard cubic foot",
name2 = "standard cubic foot",
symbol = "scf",
utype = "energy",
scale = 2869.2044809344,
default = "kJ",
},
["t(TNT)"] = {
name1 = "tonne",
name1_us = "ton",
symbol = "t",
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["TeV"] = {
name1 = "teraelectronvolt",
symbol = "TeV",
utype = "energy",
scale = 1.602176487e-7,
default = "μJ",
link = "Electronvolt",
},
["th"] = {
name1 = "thermie",
symbol = "th",
utype = "energy",
scale = 4186800,
default = "MJ",
link = "Conversion of units#Energy",
},
["thm-EC"] = {
name1 = "therm (EC)",
name2 = "therms (EC)",
symbol = "thm (EC)",
utype = "energy",
scale = 105506000,
default = "MJ",
link = "Therm",
},
["thm-UK"] = {
name1 = "therm (UK)",
name2 = "therms (UK)",
symbol = "thm (UK)",
utype = "energy",
scale = 105505585.257348,
default = "MJ",
link = "Therm",
},
["thm-US"] = {
name1 = "therm (US)",
name1_us = "therm (U.S.)",
name2 = "therms (US)",
name2_us = "therms (U.S.)",
symbol = "thm (US)",
sym_us = "thm (U.S.)",
utype = "energy",
scale = 105480400,
default = "MJ",
link = "Therm",
},
["toe"] = {
name1 = "tonne of oil equivalent",
name2 = "tonnes of oil equivalent",
symbol = "toe",
utype = "energy",
scale = 41868000000,
default = "GJ",
},
["tonTNT"] = {
name2 = "tons of TNT",
symbol = "ton of TNT",
usename = 1,
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["tTNT"] = {
name2 = "tonnes of TNT",
symbol = "tonne of TNT",
usename = 1,
utype = "energy",
scale = 4184000000,
default = "GJ",
link = "TNT equivalent",
},
["TtonTNT"] = {
name2 = "teratons of TNT",
symbol = "teraton of TNT",
usename = 1,
utype = "energy",
scale = 4.184e21,
default = "ZJ",
link = "TNT equivalent",
},
["TtTNT"] = {
name2 = "teratonnes of TNT",
symbol = "teratonne of TNT",
usename = 1,
utype = "energy",
scale = 4.184e21,
default = "ZJ",
link = "TNT equivalent",
},
["TW.h"] = {
name1 = "terawatt-hour",
symbol = "TW⋅h",
utype = "energy",
scale = 3.6e15,
default = "PJ",
link = "Kilowatt-hour",
},
["TWh"] = {
name1 = "terawatt-hour",
symbol = "TWh",
utype = "energy",
scale = 3.6e15,
default = "PJ",
link = "Kilowatt-hour",
},
["W.h"] = {
name1 = "watt-hour",
symbol = "W⋅h",
utype = "energy",
scale = 3600,
default = "kJ",
link = "Kilowatt-hour",
},
["Wh"] = {
name1 = "watt-hour",
symbol = "Wh",
utype = "energy",
scale = 3600,
default = "kJ",
link = "Kilowatt-hour",
},
["μerg"] = {
name1 = "microerg",
symbol = "μerg",
utype = "energy",
scale = 1e-13,
default = "nJ",
link = "Erg",
},
["μeV"] = {
name1 = "microelectronvolt",
symbol = "μeV",
utype = "energy",
scale = 1.602176487e-25,
default = "yJ",
link = "Electronvolt",
},
["μW.h"] = {
name1 = "microwatt-hour",
symbol = "μW⋅h",
utype = "energy",
scale = 0.0036,
default = "mJ",
link = "Kilowatt-hour",
},
["μWh"] = {
name1 = "microwatt-hour",
symbol = "μWh",
utype = "energy",
scale = 0.0036,
default = "mJ",
link = "Kilowatt-hour",
},
["-kW.h"] = {
target = "kW.h",
link = "Kilowatt hour",
},
["btu"] = {
target = "BTU",
},
["Calorie"] = {
target = "Cal",
},
["ft.lbf"] = {
target = "ftlbf",
},
["ft·lbf"] = {
target = "ftlbf",
},
["g-cal-15"] = {
target = "cal-15",
},
["g-cal-IT"] = {
target = "cal-IT",
},
["g-cal-th"] = {
target = "cal-th",
},
["g-kcal-15"] = {
target = "kcal-15",
},
["g-kcal-IT"] = {
target = "kcal-IT",
},
["g-kcal-th"] = {
target = "kcal-th",
},
["g-Mcal-15"] = {
target = "Mcal-15",
},
["g-mcal-15"] = {
target = "mcal-15",
},
["g-Mcal-IT"] = {
target = "Mcal-IT",
},
["g-mcal-IT"] = {
target = "mcal-IT",
},
["g-Mcal-th"] = {
target = "Mcal-th",
},
["g-mcal-th"] = {
target = "mcal-th",
},
["GW-h"] = {
target = "GW.h",
},
["GW·h"] = {
target = "GW.h",
},
["Hartree"] = {
target = "Eh",
},
["hp.h"] = {
target = "hph",
},
["in.lb-f"] = {
target = "inlb-f",
},
["in.lbf"] = {
target = "inlbf",
},
["in.oz-f"] = {
target = "inoz-f",
},
["in.ozf"] = {
target = "inozf",
},
["kbboe"] = {
target = "kBOE",
symbol = "kbboe",
},
["kg-cal-15"] = {
target = "Cal-15",
},
["kg-cal-IT"] = {
target = "Cal-IT",
},
["kg-cal-th"] = {
target = "Cal-th",
},
["kW-h"] = {
target = "kW.h",
},
["kW·h"] = {
target = "kW.h",
},
["MW-h"] = {
target = "MW.h",
},
["mW-h"] = {
target = "mW.h",
},
["MW·h"] = {
target = "MW.h",
},
["TW-h"] = {
target = "TW.h",
},
["uerg"] = {
target = "μerg",
},
["ueV"] = {
target = "μeV",
},
["uW-h"] = {
target = "μW.h",
},
["uW.h"] = {
target = "μW.h",
},
["uWh"] = {
target = "μWh",
},
["W-h"] = {
target = "W.h",
},
["eVpar"] = {
_name1 = "electronvolt",
_symbol = "eV",
utype = "energy per chemical amount",
scale = 96485.329522144166,
prefixes = 1,
default = "kcal/mol",
link = "Electronvolt",
},
["kcal/mol"] = {
per = { "kcal", "mol" },
utype = "energy per chemical amount",
default = "kJ/mol",
link = "Kilocalorie per mole",
},
["kJ/mol"] = {
per = { "kJ", "mol" },
utype = "energy per chemical amount",
default = "kcal/mol",
link = "Joule per mole",
},
["kWh/100 km"] = {
name1 = "kilowatt-hour per 100 kilometres",
name1_us = "kilowatt-hour per 100 kilometers",
name2 = "kilowatt-hours per 100 kilometres",
name2_us = "kilowatt-hours per 100 kilometers",
symbol = "kW⋅h/100 km",
utype = "energy per unit length",
scale = 36,
default = "MJ/km kWh/mi",
link = "Kilowatt-hour",
},
["kWh/100 mi"] = {
name1 = "kilowatt-hour per 100 miles",
name2 = "kilowatt-hours per 100 miles",
symbol = "kW⋅h/100 mi",
utype = "energy per unit length",
scale = 22.3694,
default = "mpge",
link = "Miles per gallon gasoline equivalent",
},
["MJ/100 km"] = {
name1 = "megajoule per 100 kilometres",
name1_us = "megajoule per 100 kilometers",
name2 = "megajoules per 100 kilometres",
name2_us = "megajoules per 100 kilometers",
symbol = "MJ/100 km",
utype = "energy per unit length",
scale = 10,
default = "BTU/mi",
link = "British thermal unit",
},
["mpge"] = {
name1 = "mile per gallon gasoline equivalent",
name2 = "miles per gallon gasoline equivalent",
symbol = "mpg‑e",
utype = "energy per unit length",
scale = 13e-6,
invert = -1,
iscomplex= true,
default = "kWh/100 mi",
link = "Miles per gallon gasoline equivalent",
},
["BTU/mi"] = {
per = { "BTU", "mi" },
utype = "energy per unit length",
default = "v > 1525 ! M ! k ! J/km",
},
["kJ/km"] = {
per = { "kJ", "km" },
utype = "energy per unit length",
default = "BTU/mi",
},
["kWh/km"] = {
per = { "-kW.h", "km" },
utype = "energy per unit length",
default = "MJ/km kWh/mi",
},
["kWh/mi"] = {
per = { "-kW.h", "mi" },
utype = "energy per unit length",
default = "kWh/km MJ/km",
},
["MJ/km"] = {
per = { "MJ", "km" },
utype = "energy per unit length",
default = "BTU/mi",
},
["mpg-e"] = {
target = "mpge",
},
["BTU/lb"] = {
name1 = "British thermal unit per pound",
name2 = "British thermal units per pound",
symbol = "BTU/lb",
utype = "energy per unit mass",
scale = 429.92261414790346,
default = "kJ/kg",
link = "British thermal unit",
},
["cal/g"] = {
name1 = "calorie per gram",
name2 = "calories per gram",
symbol = "cal/g",
utype = "energy per unit mass",
scale = 4184,
default = "J/g",
},
["GJ/kg"] = {
name1 = "gigajoule per kilogram",
name2 = "gigajoules per kilogram",
symbol = "GJ/kg",
utype = "energy per unit mass",
scale = 1e9,
default = "ktTNT/t",
link = "Specific energy",
},
["J/g"] = {
name1 = "joule per gram",
name2 = "joules per gram",
symbol = "J/g",
utype = "energy per unit mass",
scale = 1000,
default = "kcal/g",
link = "Specific energy",
},
["kcal/g"] = {
name1 = "kilocalorie per gram",
name2 = "kilocalories per gram",
symbol = "kcal/g",
utype = "energy per unit mass",
scale = 4184000,
default = "kJ/g",
},
["kJ/g"] = {
name1 = "kilojoule per gram",
name2 = "kilojoules per gram",
symbol = "kJ/g",
utype = "energy per unit mass",
scale = 1000000,
default = "kcal/g",
link = "Specific energy",
},
["kJ/kg"] = {
name1 = "kilojoule per kilogram",
name2 = "kilojoules per kilogram",
symbol = "kJ/kg",
utype = "energy per unit mass",
scale = 1000,
default = "BTU/lb",
link = "Specific energy",
},
["ktonTNT/MT"] = {
name2 = "kilotons of TNT per metric ton",
symbol = "kiloton of TNT per metric ton",
usename = 1,
utype = "energy per unit mass",
scale = 4184000000,
default = "GJ/kg",
link = "TNT equivalent",
},
["ktTNT/t"] = {
name2 = "kilotonnes of TNT per tonne",
symbol = "kilotonne of TNT per tonne",
usename = 1,
utype = "energy per unit mass",
scale = 4184000000,
default = "GJ/kg",
link = "TNT equivalent",
},
["MtonTNT/MT"] = {
name2 = "megatons of TNT per metric ton",
symbol = "megaton of TNT per metric ton",
usename = 1,
utype = "energy per unit mass",
scale = 4.184e12,
default = "TJ/kg",
link = "TNT equivalent",
},
["MtTNT/MT"] = {
name2 = "megatonnes of TNT per tonne",
symbol = "megatonne of TNT per tonne",
usename = 1,
utype = "energy per unit mass",
scale = 4.184e12,
default = "TJ/kg",
link = "TNT equivalent",
},
["TJ/kg"] = {
name1 = "terajoule per kilogram",
name2 = "terajoules per kilogram",
symbol = "TJ/kg",
utype = "energy per unit mass",
scale = 1e12,
default = "MtTNT/MT",
link = "Specific energy",
},
["Cal/g"] = {
per = { "Cal", "g" },
utype = "energy per unit mass",
default = "kJ/g",
},
["BTU/cuft"] = {
per = { "BTU", "cuft" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/12USoz(mL)serve"] = {
per = { "Cal", "-12USoz(mL)serve" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/12USoz(ml)serve"] = {
per = { "Cal", "-12USoz(ml)serve" },
utype = "energy per unit volume",
default = "kJ/l",
},
["Cal/12USozserve"] = {
per = { "Cal", "-12USozserve" },
utype = "energy per unit volume",
default = "kJ/L",
},
["Cal/USoz"] = {
per = { "Cal", "USoz" },
utype = "energy per unit volume",
default = "kJ/ml",
},
["kJ/L"] = {
per = { "kJ", "L" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["kJ/l"] = {
per = { "kJ", "l" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["kJ/ml"] = {
per = { "kJ", "ml" },
utype = "energy per unit volume",
default = "Cal/USoz",
},
["MJ/m3"] = {
per = { "MJ", "m3" },
utype = "energy per unit volume",
default = "BTU/cuft",
},
["Sv"] = {
_name1 = "sievert",
_symbol = "Sv",
utype = "equivalent radiation dose",
scale = 1,
prefixes = 1,
default = "rem",
link = "Sievert",
},
["rem"] = {
_name1 = "rem",
_symbol = "rem",
utype = "equivalent radiation dose",
scale = 0.01,
prefixes = 1,
default = "Sv",
link = "Roentgen equivalent man",
},
["g/km"] = {
name1 = "gram per kilometre",
name1_us = "gram per kilometer",
name2 = "grams per kilometre",
name2_us = "grams per kilometer",
symbol = "g/km",
utype = "exhaust emission",
scale = 1e-6,
default = "oz/mi",
link = "Exhaust gas",
},
["g/mi"] = {
name1 = "gram per mile",
name2 = "grams per mile",
symbol = "g/mi",
utype = "exhaust emission",
scale = 6.2137119223733397e-7,
default = "g/km",
link = "Exhaust gas",
},
["gCO2/km"] = {
name1 = "gram of CO<sub>2</sub> per kilometre",
name1_us = "gram of CO<sub>2</sub> per kilometer",
name2 = "grams of CO<sub>2</sub> per kilometre",
name2_us = "grams of CO<sub>2</sub> per kilometer",
symbol = "g(CO<sub>2</sub>)/km",
utype = "exhaust emission",
scale = 1e-6,
default = "ozCO2/mi",
link = "Exhaust gas",
},
["gCO2/mi"] = {
name1 = "gram of CO<sub>2</sub> per mile",
name2 = "grams of CO<sub>2</sub> per mile",
symbol = "g(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 6.2137119223733397e-7,
default = "gCO2/km",
link = "Exhaust gas",
},
["kg/km"] = {
name1 = "kilogram per kilometre",
name1_us = "kilogram per kilometer",
name2 = "kilograms per kilometre",
name2_us = "kilograms per kilometer",
symbol = "kg/km",
utype = "exhaust emission",
scale = 0.001,
default = "lb/mi",
link = "Exhaust gas",
},
["kgCO2/km"] = {
name1 = "kilogram of CO<sub>2</sub> per kilometre",
name1_us = "kilogram of CO<sub>2</sub> per kilometer",
name2 = "kilograms of CO<sub>2</sub> per kilometre",
name2_us = "kilograms of CO<sub>2</sub> per kilometer",
symbol = "kg(CO<sub>2</sub>)/km",
utype = "exhaust emission",
scale = 0.001,
default = "lbCO2/mi",
link = "Exhaust gas",
},
["lb/mi"] = {
name1 = "pound per mile",
name2 = "pounds per mile",
symbol = "lb/mi",
utype = "exhaust emission",
scale = 0.00028184923173665794,
default = "kg/km",
link = "Exhaust gas",
},
["lbCO2/mi"] = {
name1 = "pound of CO<sub>2</sub> per mile",
name2 = "pounds of CO<sub>2</sub> per mile",
symbol = "lb(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 0.00028184923173665794,
default = "kgCO2/km",
link = "Exhaust gas",
},
["oz/mi"] = {
name1 = "ounce per mile",
name2 = "ounces per mile",
symbol = "oz/mi",
utype = "exhaust emission",
scale = 1.7615576983541121e-5,
default = "g/km",
link = "Exhaust gas",
},
["ozCO2/mi"] = {
name1 = "ounce of CO<sub>2</sub> per mile",
name2 = "ounces of CO<sub>2</sub> per mile",
symbol = "oz(CO<sub>2</sub>)/mi",
utype = "exhaust emission",
scale = 1.7615576983541121e-5,
default = "gCO2/km",
link = "Exhaust gas",
},
["cuft/a"] = {
name1 = "cubic foot per annum",
name2 = "cubic feet per annum",
symbol = "cu ft/a",
utype = "flow",
scale = 8.9730672142368242e-10,
default = "m3/a",
link = "Cubic foot per second",
},
["cuft/d"] = {
name1 = "cubic foot per day",
name2 = "cubic feet per day",
symbol = "cu ft/d",
utype = "flow",
scale = 3.2774128000000003e-7,
default = "m3/d",
link = "Cubic foot per second",
},
["cuft/h"] = {
name1 = "cubic foot per hour",
name2 = "cubic feet per hour",
symbol = "cu ft/h",
utype = "flow",
scale = 7.8657907200000004e-6,
default = "m3/h",
link = "Cubic foot per second",
},
["cuft/min"] = {
name1 = "cubic foot per minute",
name2 = "cubic feet per minute",
symbol = "cu ft/min",
utype = "flow",
scale = 0.00047194744319999999,
default = "m3/min",
},
["cuft/s"] = {
name1 = "cubic foot per second",
name2 = "cubic feet per second",
symbol = "cu ft/s",
utype = "flow",
scale = 28316846592e-12,
default = "m3/s",
},
["cumi/a"] = {
name1 = "cubic mile per annum",
name2 = "cubic miles per annum",
symbol = "cu mi/a",
utype = "flow",
scale = 132.08171170940057,
default = "km3/a",
link = "Cubic foot per second",
},
["cuyd/h"] = {
name1 = "cubic yard per hour",
name2 = "cubic yards per hour",
symbol = "cuyd/h",
utype = "flow",
scale = 0.00021237634944000001,
default = "m3/h",
link = "Cubic foot per second",
},
["cuyd/s"] = {
name1 = "cubic yard per second",
name2 = "cubic yards per second",
symbol = "cu yd/s",
utype = "flow",
scale = 0.76455485798400002,
default = "m3/s",
},
["Goilbbl/a"] = {
name1 = "billion barrels per year",
name2 = "billion barrels per year",
symbol = "Gbbl/a",
utype = "flow",
scale = 5.0380033629933836,
default = "v * 1.58987294928 < 10 ! e6 ! e9 ! m3/a",
link = "Barrel per day",
},
["impgal/h"] = {
name1 = "imperial gallon per hour",
name2 = "imperial gallons per hour",
symbol = "imp gal/h",
utype = "flow",
scale = 1.2628027777777779e-6,
default = "m3/h",
link = "Gallon",
},
["impgal/min"] = {
name1 = "imperial gallon per minute",
name2 = "imperial gallons per minute",
symbol = "imp gal/min",
utype = "flow",
scale = 7.5768166666666671e-5,
default = "m3/s",
link = "Gallon",
},
["impgal/s"] = {
name1 = "imperial gallon per second",
name2 = "imperial gallons per second",
symbol = "impgal/s",
utype = "flow",
scale = 0.00454609,
default = "m3/s",
link = "Imperial gallons per second",
},
["km3/a"] = {
name1 = "cubic kilometre per annum",
name1_us = "cubic kilometer per annum",
name2 = "cubic kilometres per annum",
name2_us = "cubic kilometers per annum",
symbol = "km<sup>3</sup>/a",
utype = "flow",
scale = 31.68808781402895,
default = "cumi/a",
link = "Cubic metre per second",
},
["km3/d"] = {
name1 = "cubic kilometre per day",
name1_us = "cubic kilometer per day",
name2 = "cubic kilometres per day",
name2_us = "cubic kilometers per day",
symbol = "km<sup>3</sup>/d",
utype = "flow",
scale = 11574.074074074075,
default = "cuft/d",
link = "Cubic metre per second",
},
["koilbbl/a"] = {
name1 = "thousand barrels per year",
name2 = "thousand barrels per year",
symbol = "kbbl/a",
utype = "flow",
scale = 5.0380033629933841e-6,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3/a",
link = "Barrel per day",
},
["koilbbl/d"] = {
name1 = "thousand barrels per day",
name2 = "thousand barrels per day",
symbol = "kbbl/d",
utype = "flow",
scale = 0.0018401307283333335,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3/d",
link = "Barrel per day",
},
["L/h"] = {
name1 = "litre per hour",
name1_us = "liter per hour",
name2 = "litres per hour",
name2_us = "liters per hour",
symbol = "L/h",
utype = "flow",
scale = 2.7777777777777776e-7,
default = "impgal/h USgal/h",
link = "Cubic metre per second",
},
["L/min"] = {
name1 = "litre per minute",
name1_us = "liter per minute",
name2 = "litres per minute",
name2_us = "liters per minute",
symbol = "L/min",
utype = "flow",
scale = 1.6666666666666667e-5,
default = "impgal/min USgal/min",
link = "Cubic metre per second",
},
["L/s"] = {
name1 = "litre per second",
name1_us = "liter per second",
name2 = "litres per second",
name2_us = "liters per second",
symbol = "L/s",
utype = "flow",
scale = 0.001,
default = "cuft/s",
link = "Cubic metre per second",
},
["m3/a"] = {
name1 = "cubic metre per annum",
name1_us = "cubic meter per annum",
name2 = "cubic metres per annum",
name2_us = "cubic meters per annum",
symbol = "m<sup>3</sup>/a",
utype = "flow",
scale = 3.1688087814028947e-8,
default = "cuft/a",
link = "Cubic metre per second",
},
["m3/d"] = {
name1 = "cubic metre per day",
name1_us = "cubic meter per day",
name2 = "cubic metres per day",
name2_us = "cubic meters per day",
symbol = "m<sup>3</sup>/d",
utype = "flow",
scale = 1.1574074074074073e-5,
default = "cuft/d",
link = "Cubic metre per second",
},
["m3/h"] = {
name1 = "cubic metre per hour",
name1_us = "cubic meter per hour",
name2 = "cubic metres per hour",
name2_us = "cubic meters per hour",
symbol = "m<sup>3</sup>/h",
utype = "flow",
scale = 0.00027777777777777778,
default = "cuft/h",
link = "Cubic metre per second",
},
["m3/min"] = {
name1 = "cubic metre per minute",
name1_us = "cubic meter per minute",
name2 = "cubic metres per minute",
name2_us = "cubic meters per minute",
symbol = "m<sup>3</sup>/min",
utype = "flow",
scale = 0.016666666666666666,
default = "cuft/min",
link = "Cubic metre per second",
},
["m3/s"] = {
name1 = "cubic metre per second",
name1_us = "cubic meter per second",
name2 = "cubic metres per second",
name2_us = "cubic meters per second",
symbol = "m<sup>3</sup>/s",
utype = "flow",
scale = 1,
default = "cuft/s",
},
["Moilbbl/a"] = {
name1 = "million barrels per year",
name2 = "million barrels per year",
symbol = "Mbbl/a",
utype = "flow",
scale = 0.0050380033629933837,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3/a",
link = "Barrel per day",
},
["Moilbbl/d"] = {
name1 = "million barrels per day",
name2 = "million barrels per day",
symbol = "Mbbl/d",
utype = "flow",
scale = 1.8401307283333335,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3/d",
link = "Barrel per day",
},
["oilbbl/a"] = {
name1 = "barrel per year",
name2 = "barrels per year",
symbol = "bbl/a",
utype = "flow",
scale = 5.0380033629933841e-9,
default = "m3/a",
link = "Barrel per day",
},
["oilbbl/d"] = {
name1 = "barrel per day",
name2 = "barrels per day",
symbol = "bbl/d",
utype = "flow",
scale = 1.8401307283333336e-6,
default = "m3/d",
},
["Toilbbl/a"] = {
name1 = "trillion barrels per year",
name2 = "trillion barrels per year",
symbol = "Tbbl/a",
utype = "flow",
scale = 5038.0033629933832,
default = "v * 1.58987294928 < 10 ! e9 ! e12 ! m3/a",
link = "Barrel per day",
},
["U.S.gal/d"] = {
name1 = "U.S. gallon per day",
name2 = "U.S. gallons per day",
symbol = "U.S. gal/d",
utype = "flow",
scale = 4.3812636388888893e-8,
default = "m3/s",
customary= 1,
},
["U.S.gal/h"] = {
name1 = "gallon per hour",
name2 = "gallons per hour",
symbol = "gal/h",
utype = "flow",
scale = 1.0515032733333334e-6,
default = "m3/h",
link = "Gallon",
customary= 2,
},
["U.S.gal/min"] = {
name1 = "U.S. gallon per minute",
name2 = "U.S. gallons per minute",
symbol = "U.S. gal/min",
utype = "flow",
scale = 6.3090196400000003e-5,
default = "m3/s",
link = "Gallon",
},
["USgal/a"] = {
name1 = "US gallon per year",
name2 = "US gallons per year",
symbol = "US gal/a",
utype = "flow",
scale = 1.1995246102365199e-10,
default = "m3/s",
},
["USgal/d"] = {
name1 = "US gallon per day",
name2 = "US gallons per day",
symbol = "US gal/d",
utype = "flow",
scale = 4.3812636388888893e-8,
default = "m3/s",
},
["USgal/h"] = {
name1 = "gallon per hour",
name2 = "gallons per hour",
symbol = "gal/h",
utype = "flow",
scale = 1.0515032733333334e-6,
default = "m3/h",
link = "Gallon",
customary= 1,
},
["USgal/min"] = {
name1 = "US gallon per minute",
name2 = "US gallons per minute",
symbol = "US gal/min",
utype = "flow",
scale = 6.3090196400000003e-5,
default = "m3/s",
link = "Gallon",
},
["USgal/s"] = {
name1 = "US gallon per second",
name1_us = "U.S. gallon per second",
name2 = "US gallons per second",
name2_us = "U.S. gallons per second",
symbol = "USgal/s",
utype = "flow",
scale = 0.003785411784,
default = "m3/s",
link = "US gallons per second",
},
["ft3/a"] = {
target = "cuft/a",
},
["ft3/d"] = {
target = "cuft/d",
},
["ft3/h"] = {
target = "cuft/h",
},
["ft3/s"] = {
target = "cuft/s",
},
["Gcuft/a"] = {
target = "e9cuft/a",
},
["Gcuft/d"] = {
target = "e9cuft/d",
},
["kcuft/a"] = {
target = "e3cuft/a",
},
["kcuft/d"] = {
target = "e3cuft/d",
},
["kcuft/s"] = {
target = "e3cuft/s",
},
["Mcuft/a"] = {
target = "e6cuft/a",
},
["Mcuft/d"] = {
target = "e6cuft/d",
},
["Mcuft/s"] = {
target = "e6cuft/s",
},
["m³/s"] = {
target = "m3/s",
},
["Tcuft/a"] = {
target = "e12cuft/a",
},
["Tcuft/d"] = {
target = "e12cuft/d",
},
["u.s.gal/min"] = {
target = "U.S.gal/min",
},
["usgal/min"] = {
target = "USgal/min",
},
["-LTf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LTf",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["-STf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "STf",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["dyn"] = {
name1 = "dyne",
symbol = "dyn",
utype = "force",
scale = 0.00001,
default = "gr-f",
},
["g-f"] = {
name1 = "gram-force",
name2 = "grams-force",
symbol = "g<sub>f</sub>",
utype = "force",
scale = 0.00980665,
default = "mN oz-f",
link = "Kilogram-force",
},
["gf"] = {
name1 = "gram-force",
name2 = "grams-force",
symbol = "gf",
utype = "force",
scale = 0.00980665,
default = "mN ozf",
link = "Kilogram-force",
},
["gr-f"] = {
name1 = "grain-force",
name2 = "grains-force",
symbol = "gr<sub>f</sub>",
utype = "force",
scale = 0.0006354602307515,
default = "μN",
link = "Pound (force)",
},
["grf"] = {
name1 = "grain-force",
name2 = "grains-force",
symbol = "grf",
utype = "force",
scale = 0.0006354602307515,
default = "μN",
link = "Pound (force)",
},
["kdyn"] = {
name1 = "kilodyne",
symbol = "kdyn",
utype = "force",
scale = 0.01,
default = "oz-f",
link = "Dyne",
},
["kg-f"] = {
name1 = "kilogram-force",
name2 = "kilograms-force",
symbol = "kg<sub>f</sub>",
utype = "force",
scale = 9.80665,
default = "N lb-f",
},
["kgf"] = {
name1 = "kilogram-force",
name2 = "kilograms-force",
symbol = "kgf",
utype = "force",
scale = 9.80665,
default = "N lbf",
},
["kp"] = {
name1 = "kilopond",
symbol = "kp",
utype = "force",
scale = 9.80665,
default = "N lb-f",
link = "Kilogram-force",
},
["L/T-f"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "L/T<sub>f</sub>",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["L/Tf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "L/Tf",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["lb-f"] = {
name1 = "pound-force",
name2 = "pounds-force",
symbol = "lb<sub>f</sub>",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["lbf"] = {
name1 = "pound-force",
name2 = "pounds-force",
symbol = "lbf",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["lb(f)"] = {
name1 = "pound",
symbol = "lb",
utype = "force",
scale = 4.4482216152605,
default = "N",
link = "Pound (force)",
},
["LT-f"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LT<sub>f</sub>",
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["LTf"] = {
name1 = "long ton-force",
name2 = "long tons-force",
symbol = "LTf",
usename = 1,
utype = "force",
scale = 9964.01641818352,
default = "kN",
},
["Mdyn"] = {
name1 = "megadyne",
symbol = "Mdyn",
utype = "force",
scale = 10,
default = "lb-f",
link = "Dyne",
},
["mdyn"] = {
name1 = "millidyne",
symbol = "mdyn",
utype = "force",
scale = 0.00000001,
default = "gr-f",
link = "Dyne",
},
["mg-f"] = {
name1 = "milligram-force",
name2 = "milligrams-force",
symbol = "mg<sub>f</sub>",
utype = "force",
scale = 0.00000980665,
default = "μN gr-f",
link = "Kilogram-force",
},
["mgf"] = {
name1 = "milligram-force",
name2 = "milligrams-force",
symbol = "mgf",
utype = "force",
scale = 0.00000980665,
default = "μN grf",
link = "Kilogram-force",
},
["Mp"] = {
name1 = "megapond",
symbol = "Mp",
utype = "force",
scale = 9806.65,
default = "kN LT-f ST-f",
link = "Kilogram-force",
},
["mp"] = {
name1 = "millipond",
symbol = "mp",
utype = "force",
scale = 0.00000980665,
default = "μN gr-f",
link = "Kilogram-force",
},
["N"] = {
_name1 = "newton",
_symbol = "N",
utype = "force",
scale = 1,
prefixes = 1,
default = "lb-f",
link = "Newton (unit)",
},
["oz-f"] = {
name1 = "ounce-force",
name2 = "ounces-force",
symbol = "oz<sub>f</sub>",
utype = "force",
scale = 0.2780138203095378125,
default = "mN",
link = "Pound (force)",
},
["ozf"] = {
name1 = "ounce-force",
name2 = "ounces-force",
symbol = "ozf",
utype = "force",
scale = 0.2780138203095378125,
default = "mN",
link = "Pound (force)",
},
["p"] = {
name1 = "pond",
symbol = "p",
utype = "force",
scale = 0.00980665,
default = "mN oz-f",
link = "Kilogram-force",
},
["pdl"] = {
name1 = "poundal",
symbol = "pdl",
utype = "force",
scale = 0.138254954376,
default = "N",
},
["S/T-f"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "S/T<sub>f</sub>",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["S/Tf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "S/Tf",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["ST-f"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "ST<sub>f</sub>",
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["STf"] = {
name1 = "short ton-force",
name2 = "short tons-force",
symbol = "STf",
usename = 1,
utype = "force",
scale = 8896.443230521,
default = "kN",
},
["t-f"] = {
name1 = "tonne-force",
name2 = "tonnes-force",
symbol = "t<sub>f</sub>",
utype = "force",
scale = 9806.65,
default = "kN LT-f ST-f",
link = "Ton-force#Tonne-force",
},
["tf"] = {
name1 = "tonne-force",
name2 = "tonnes-force",
symbol = "tf",
utype = "force",
scale = 9806.65,
default = "kN LTf STf",
link = "Ton-force#Tonne-force",
},
["dyne"] = {
target = "dyn",
},
["newtons"] = {
target = "N",
},
["poundal"] = {
target = "pdl",
},
["tonne-force"] = {
target = "tf",
},
["impgal/mi"] = {
per = { "@impgal", "mi" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km USgal/mi",
},
["km/L"] = {
per = { "km", "L" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "mpgimp mpgus",
},
["km/l"] = {
per = { "km", "l" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "mpgimp mpgus",
},
["L/100 km"] = {
per = { "L", "100km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|L/100 km]]",
},
["l/100 km"] = {
per = { "l", "100km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|l/100 km]]",
},
["L/km"] = {
per = { "L", "km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
},
["l/km"] = {
per = { "l", "km" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "mpgimp mpgus",
},
["mi/impqt"] = {
per = { "mi", "impqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/U.S.qt"] = {
per = { "mi", "U.S.qt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/USqt"] = {
per = { "mi", "USqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mi/usqt"] = {
per = { "mi", "usqt" },
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "km/L",
},
["mpgimp"] = {
per = { "mi", "@impgal" },
symbol = "mpg<sub>‑imp</sub>",
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "L/100 km+mpgus",
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[Imperial units|imp]]</sub>",
},
["mpgus"] = {
per = { "mi", "+USgal" },
symbol = "mpg<sub>‑US</sub>",
utype = "fuel efficiency",
invert = -1,
iscomplex= true,
default = "L/100 km+mpgimp",
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|US]]</sub>",
},
["U.S.gal/mi"] = {
per = { "*U.S.gal", "mi" },
sp_us = true,
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km impgal/mi",
},
["usgal/mi"] = {
per = { "+USgal", "mi" },
utype = "fuel efficiency",
invert = 1,
iscomplex= true,
default = "l/km impgal/mi",
},
["L/100km"] = {
target = "L/100 km",
},
["l/100km"] = {
target = "l/100 km",
},
["mpg"] = {
shouldbe = "Use %{mpgus%} for miles per US gallon or %{mpgimp%} for miles per imperial gallon (not %{mpg%})",
},
["mpgU.S."] = {
target = "mpgus",
symbol = "mpg<sub>‑U.S.</sub>",
sp_us = true,
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|U.S.]]</sub>",
},
["mpgu.s."] = {
target = "mpgus",
symbol = "mpg<sub>‑U.S.</sub>",
sp_us = true,
symlink = "[[Fuel economy in automobiles#Units of measure|mpg]]<sub>‑[[United States customary units|U.S.]]</sub>",
},
["mpgUS"] = {
target = "mpgus",
},
["USgal/mi"] = {
target = "usgal/mi",
},
["kPa/m"] = {
per = { "kPa", "-m-frac" },
utype = "fracture gradient",
default = "psi/ft",
},
["psi/ft"] = {
per = { "psi", "-ft-frac" },
utype = "fracture gradient",
default = "kPa/m",
},
["cm/km"] = {
name1 = "centimetre per kilometre",
name1_us = "centimeter per kilometer",
name2 = "centimetres per kilometre",
name2_us = "centimeters per kilometer",
symbol = "cm/km",
utype = "gradient",
scale = 0.00001,
default = "ft/mi",
link = "Grade (slope)",
},
["ft/mi"] = {
name1 = "foot per mile",
name2 = "feet per mile",
symbol = "ft/mi",
utype = "gradient",
scale = 0.00018939393939393939,
default = "v < 5.28 ! c ! ! m/km",
link = "Grade (slope)",
},
["ft/nmi"] = {
name1 = "foot per nautical mile",
name2 = "feet per nautical mile",
symbol = "ft/nmi",
utype = "gradient",
scale = 0.00016457883369330455,
default = "v < 6.076 ! c ! ! m/km",
link = "Grade (slope)",
},
["in/ft"] = {
name1 = "inch per foot",
name2 = "inches per foot",
symbol = "in/ft",
utype = "gradient",
scale = 0.083333333333333329,
default = "mm/m",
link = "Grade (slope)",
},
["in/mi"] = {
name1 = "inch per mile",
name2 = "inches per mile",
symbol = "in/mi",
utype = "gradient",
scale = 1.5782828282828283e-5,
default = "v < 0.6336 ! m ! c ! m/km",
link = "Grade (slope)",
},
["m/km"] = {
name1 = "metre per kilometre",
name1_us = "meter per kilometer",
name2 = "metres per kilometre",
name2_us = "meters per kilometer",
symbol = "m/km",
utype = "gradient",
scale = 0.001,
default = "ft/mi",
link = "Grade (slope)",
},
["mm/km"] = {
name1 = "millimetre per kilometre",
name1_us = "millimeter per kilometer",
name2 = "millimetres per kilometre",
name2_us = "millimeters per kilometer",
symbol = "mm/km",
utype = "gradient",
scale = 0.000001,
default = "in/mi",
link = "Grade (slope)",
},
["mm/m"] = {
name1 = "millimetre per metre",
name1_us = "millimeter per meter",
name2 = "millimetres per metre",
name2_us = "millimeters per meter",
symbol = "mm/m",
utype = "gradient",
scale = 0.001,
default = "in/ft",
link = "Grade (slope)",
},
["admi"] = {
name1 = "admiralty mile",
symbol = "nmi (admiralty)",
utype = "length",
scale = 1853.184,
default = "km mi",
link = "Nautical mile",
},
["AU"] = {
name1 = "astronomical unit",
symbol = "AU",
utype = "length",
scale = 149597870700,
default = "km mi",
},
["Brnmi"] = {
name1 = "British nautical mile",
symbol = "(Brit) nmi",
utype = "length",
scale = 1853.184,
default = "km mi",
link = "Nautical mile",
},
["bu"] = {
name2 = "bu",
symbol = "bu",
usename = 1,
utype = "length",
scale = 0.0030303030303030303,
default = "mm",
link = "Japanese units of measurement#Length",
},
["ch"] = {
name1 = "chain",
symbol = "ch",
utype = "length",
scale = 20.1168,
default = "ft m",
subdivs = { ["ft"] = { 66, default = "m" }, ["yd"] = { 22, default = "m" } },
link = "Chain (unit)",
},
["chlk"] = {
name1 = "[[Chain (unit)|chain]]",
symbol = "[[Chain (unit)|ch]]",
utype = "length",
scale = 20.1168,
default = "ft m",
link = "",
},
["chain"] = {
symbol = "chain",
usename = 1,
utype = "length",
scale = 20.1168,
default = "ft m",
subdivs = { ["ft"] = { 66, default = "m" }, ["yd"] = { 22, default = "m" } },
link = "Chain (unit)",
},
["chainlk"] = {
symbol = "[[Chain (unit)|chain]]",
usename = 1,
utype = "length",
scale = 20.1168,
default = "ft m",
link = "",
},
["dpcm"] = {
name2 = "dot/cm",
symbol = "dot/cm",
utype = "length",
scale = 100,
invert = -1,
iscomplex= true,
default = "dpi",
link = "Dots per inch",
},
["dpi"] = {
name2 = "DPI",
symbol = "DPI",
utype = "length",
scale = 39.370078740157481,
invert = -1,
iscomplex= true,
default = "pitch",
link = "Dots per inch",
},
["fathom"] = {
symbol = "fathom",
usename = 1,
utype = "length",
scale = 1.8288,
default = "ft m",
},
["foot"] = {
name1 = "foot",
name2 = "foot",
symbol = "ft",
utype = "length",
scale = 0.3048,
default = "m",
subdivs = { ["in"] = { 12, default = "m" } },
link = "Foot (unit)",
},
["ft"] = {
name1 = "foot",
name2 = "feet",
symbol = "ft",
utype = "length",
scale = 0.3048,
exception= "integer_more_precision",
default = "m",
subdivs = { ["in"] = { 12, default = "m" } },
link = "Foot (unit)",
},
["furlong"] = {
symbol = "furlong",
usename = 1,
utype = "length",
scale = 201.168,
default = "ft m",
},
["Gly"] = {
name1 = "gigalight-year",
symbol = "Gly",
utype = "length",
scale = 9.4607304725808e24,
default = "Mpc",
link = "Light-year#Definitions",
},
["Gpc"] = {
name1 = "gigaparsec",
symbol = "Gpc",
utype = "length",
scale = 3.0856775814671916e25,
default = "Gly",
link = "Parsec#Megaparsecs and gigaparsecs",
},
["hand"] = {
name1 = "hand",
symbol = "h",
utype = "length",
builtin = "hand",
scale = 0.1016,
iscomplex= true,
default = "in cm",
link = "Hand (unit)",
},
["in"] = {
name1 = "inch",
name2 = "inches",
symbol = "in",
utype = "length",
scale = 0.0254,
exception= "subunit_more_precision",
default = "mm",
},
["inabbreviated"] = {
name2 = "in",
symbol = "in",
utype = "length",
scale = 0.0254,
default = "mm",
link = "Inch",
},
["kly"] = {
name1 = "kilolight-year",
symbol = "kly",
utype = "length",
scale = 9.4607304725808e18,
default = "pc",
link = "Light-year#Definitions",
},
["kpc"] = {
name1 = "kiloparsec",
symbol = "kpc",
utype = "length",
scale = 3.0856775814671916e19,
default = "kly",
link = "Parsec#Parsecs and kiloparsecs",
},
["LD"] = {
name1 = "lunar distance",
symbol = "LD",
utype = "length",
scale = 384403000,
default = "km mi",
link = "Lunar distance (astronomy)",
},
["league"] = {
symbol = "league",
usename = 1,
utype = "length",
scale = 4828.032,
default = "km",
link = "League (unit)",
},
["ly"] = {
name1 = "light-year",
symbol = "ly",
utype = "length",
scale = 9.4607304725808e15,
default = "AU",
},
["m"] = {
_name1 = "metre",
_name1_us= "meter",
_symbol = "m",
utype = "length",
scale = 1,
prefixes = 1,
default = "v > 0 and v < 3 ! ftin ! ft",
link = "Metre",
},
["mi"] = {
name1 = "mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
subdivs = { ["ch"] = { 80, default = "km" }, ["chlk"] = { 80, default = "km" }, ["chain"] = { 80, default = "km" }, ["chainlk"] = { 80, default = "km" }, ["ft"] = { 5280, default = "km" }, ["furlong"] = { 8, default = "km" }, ["yd"] = { 1760, default = "km" } },
},
["mil"] = {
symbol = "mil",
usename = 1,
utype = "length",
scale = 0.0000254,
default = "mm",
link = "Thousandth of an inch",
},
["Mly"] = {
name1 = "megalight-year",
symbol = "Mly",
utype = "length",
scale = 9.4607304725808e21,
default = "kpc",
link = "Light-year#Definitions",
},
["Mpc"] = {
name1 = "megaparsec",
symbol = "Mpc",
utype = "length",
scale = 3.0856775814671916e22,
default = "Mly",
link = "Parsec#Megaparsecs and gigaparsecs",
},
["NM"] = {
name1 = "nautical mile",
symbol = "NM",
utype = "length",
scale = 1852,
default = "km mi",
},
["nmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1852,
default = "km mi",
},
["oldUKnmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1853.184,
default = "km mi",
},
["oldUSnmi"] = {
name1 = "nautical mile",
symbol = "nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
},
["pc"] = {
name1 = "parsec",
symbol = "pc",
utype = "length",
scale = 3.0856775814671916e16,
default = "ly",
},
["perch"] = {
name2 = "perches",
symbol = "perch",
usename = 1,
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["pitch"] = {
name2 = "μm",
symbol = "μm",
utype = "length",
scale = 1e-6,
default = "dpi",
defkey = "pitch",
linkey = "pitch",
link = "Dots per inch",
},
["pole"] = {
symbol = "pole",
usename = 1,
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["pre1954U.S.nmi"] = {
name1 = "(pre-1954 U.S.) nautical mile",
symbol = "(pre‑1954 U.S.) nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
link = "Nautical mile",
},
["pre1954USnmi"] = {
name1 = "(pre-1954 US) nautical mile",
name1_us = "(pre-1954 U.S.) nautical mile",
symbol = "(pre‑1954 US) nmi",
sym_us = "(pre‑1954 U.S.) nmi",
utype = "length",
scale = 1853.24496,
default = "km mi",
link = "Nautical mile",
},
["rd"] = {
name1 = "rod",
symbol = "rd",
utype = "length",
scale = 5.0292,
default = "ft m",
link = "Rod (unit)",
},
["royal cubit"] = {
name1 = "royal cubit",
symbol = "cu",
utype = "length",
scale = 0.524,
default = "mm",
},
["rtkm"] = {
name1 = "route kilometre",
name1_us = "route kilometer",
symbol = "km",
utype = "length",
scale = 1000,
default = "mi",
link = "Kilometre",
},
["rtmi"] = {
name1 = "route mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
link = "Mile",
},
["shaku"] = {
name2 = "shaku",
symbol = "shaku",
usename = 1,
utype = "length",
scale = 0.30303030303030304,
default = "m",
link = "Shaku (unit)",
},
["sm"] = {
name1 = "smoot",
symbol = "sm",
utype = "length",
scale = 1.70180,
default = "m",
link = "Smoot (unit)",
},
["smi"] = {
name1 = "statute mile",
symbol = "mi",
utype = "length",
scale = 1609.344,
default = "km",
subdivs = { ["chain"] = { 80, default = "km" } },
},
["solar radius"] = {
name1 = "solar radius",
name2 = "solar radii",
symbol = "''R''<sub>☉</sub>",
utype = "length",
scale = 695700e3,
default = "km",
},
["sun"] = {
name2 = "sun",
symbol = "sun",
usename = 1,
utype = "length",
scale = 0.030303030303030304,
default = "mm",
link = "Japanese units of measurement#Length",
},
["thou"] = {
name2 = "thou",
symbol = "thou",
usename = 1,
utype = "length",
scale = 0.0000254,
default = "mm",
link = "Thousandth of an inch",
},
["verst"] = {
symbol = "verst",
usename = 1,
utype = "length",
scale = 1066.8,
default = "km mi",
},
["yd"] = {
name1 = "yard",
symbol = "yd",
utype = "length",
scale = 0.9144,
default = "m",
subdivs = { ["ft"] = { 3, default = "m" } },
},
["μin"] = {
name1 = "microinch",
name2 = "microinches",
symbol = "μin",
utype = "length",
scale = 0.0000000254,
default = "nm",
link = "SI prefix#Non-metric units",
},
["Å"] = {
name1 = "ångström",
symbol = "Å",
utype = "length",
scale = 0.0000000001,
default = "in",
},
["Hz"] = {
_name1 = "hertz",
_name2 = "hertz",
_symbol = "Hz",
utype = "length",
scale = 3.3356409519815204e-9,
invert = -1,
iscomplex= true,
prefixes = 1,
default = "m",
link = "Hertz",
},
["rpm"] = {
name1 = "revolution per minute",
name2 = "revolutions per minute",
symbol = "rpm",
utype = "length",
scale = 5.5594015866358675e-11,
invert = -1,
iscomplex= true,
default = "Hz",
link = "Revolutions per minute",
},
["-ft-frac"] = {
target = "ft",
link = "Fracture gradient",
},
["-in-stiff"] = {
target = "in",
link = "Stiffness",
},
["-m-frac"] = {
target = "m",
link = "Fracture gradient",
},
["-m-stiff"] = {
target = "m",
link = "Stiffness",
},
["100km"] = {
target = "km",
multiplier= 100,
},
["100mi"] = {
target = "mi",
multiplier= 100,
},
["100miles"] = {
target = "mi",
symbol = "miles",
multiplier= 100,
},
["admiralty nmi"] = {
target = "oldUKnmi",
},
["angstrom"] = {
target = "Å",
},
["au"] = {
target = "AU",
symbol = "au",
},
["feet"] = {
target = "ft",
},
["hands"] = {
target = "hand",
},
["inch"] = {
target = "in",
},
["light-year"] = {
target = "ly",
},
["meter"] = {
target = "m",
sp_us = true,
},
["meters"] = {
target = "m",
sp_us = true,
},
["metre"] = {
target = "m",
},
["metres"] = {
target = "m",
},
["micrometre"] = {
target = "μm",
},
["micron"] = {
target = "μm",
default = "μin",
},
["mile"] = {
target = "mi",
},
["miles"] = {
target = "mi",
},
["parsec"] = {
target = "pc",
},
["rod"] = {
target = "rd",
},
["smoot"] = {
target = "sm",
},
["uin"] = {
target = "μin",
},
["yard"] = {
target = "yd",
},
["yards"] = {
target = "yd",
},
["yds"] = {
target = "yd",
},
["dtex"] = {
name1 = "decitex",
name2 = "decitex",
symbol = "dtex",
utype = "linear density",
scale = 1e-7,
default = "lb/yd",
link = "Units of textile measurement#Units",
},
["kg/cm"] = {
name1 = "kilogram per centimetre",
name1_us = "kilogram per centimeter",
name2 = "kilograms per centimetre",
name2_us = "kilograms per centimeter",
symbol = "kg/cm",
utype = "linear density",
scale = 100,
default = "lb/yd",
link = "Linear density",
},
["kg/m"] = {
name1 = "kilogram per metre",
name1_us = "kilogram per meter",
name2 = "kilograms per metre",
name2_us = "kilograms per meter",
symbol = "kg/m",
utype = "linear density",
scale = 1,
default = "lb/yd",
link = "Linear density",
},
["lb/ft"] = {
name1 = "pound per foot",
name2 = "pounds per foot",
symbol = "lb/ft",
utype = "linear density",
scale = 1.4881639435695539,
default = "kg/m",
link = "Linear density",
},
["lb/yd"] = {
name1 = "pound per yard",
name2 = "pounds per yard",
symbol = "lb/yd",
utype = "linear density",
scale = 0.49605464785651798,
default = "kg/m",
link = "Linear density",
},
["G"] = {
_name1 = "gauss",
_name2 = "gauss",
_symbol = "G",
utype = "magnetic field strength",
scale = 0.0001,
prefixes = 1,
default = "T",
link = "Gauss (unit)",
},
["T"] = {
_name1 = "tesla",
_symbol = "T",
utype = "magnetic field strength",
scale = 1,
prefixes = 1,
default = "G",
link = "Tesla (unit)",
},
["A/m"] = {
name1 = "ampere per metre",
name1_us = "ampere per meter",
name2 = "amperes per metre",
name2_us = "amperes per meter",
symbol = "A/m",
utype = "magnetizing field",
scale = 1,
default = "Oe",
},
["kA/m"] = {
name1 = "kiloampere per metre",
name1_us = "kiloampere per meter",
name2 = "kiloamperes per metre",
name2_us = "kiloamperes per meter",
symbol = "kA/m",
utype = "magnetizing field",
scale = 1000,
default = "kOe",
link = "Ampere per metre",
},
["MA/m"] = {
name1 = "megaampere per metre",
name1_us = "megaampere per meter",
name2 = "megaamperes per metre",
name2_us = "megaamperes per meter",
symbol = "MA/m",
utype = "magnetizing field",
scale = 1e6,
default = "kOe",
link = "Ampere per metre",
},
["Oe"] = {
_name1 = "oersted",
_symbol = "Oe",
utype = "magnetizing field",
scale = 79.5774715,
prefixes = 1,
default = "kA/m",
link = "Oersted",
},
["-Lcwt"] = {
name1 = "hundredweight",
name2 = "hundredweight",
symbol = "cwt",
utype = "mass",
scale = 50.80234544,
default = "lb",
},
["-Scwt"] = {
name1 = "hundredweight",
name2 = "hundredweight",
symbol = "cwt",
utype = "mass",
scale = 45.359237,
default = "lb",
},
["-ST"] = {
name1 = "short ton",
symbol = "ST",
utype = "mass",
scale = 907.18474,
default = "t",
},
["carat"] = {
symbol = "carat",
usename = 1,
utype = "mass",
scale = 0.0002,
default = "g",
link = "Carat (mass)",
},
["drachm"] = {
name1_us = "dram",
symbol = "drachm",
usename = 1,
utype = "mass",
scale = 0.001771845195,
default = "g",
link = "Dram (unit)",
},
["dram"] = {
target = "drachm",
},
["dwt"] = {
name1 = "pennyweight",
symbol = "dwt",
utype = "mass",
scale = 0.00155517384,
default = "oz g",
},
["DWton"] = {
symbol = "deadweight ton",
usename = 1,
utype = "mass",
scale = 1016.0469088,
default = "DWtonne",
link = "Deadweight tonnage",
},
["DWtonne"] = {
symbol = "deadweight tonne",
usename = 1,
utype = "mass",
scale = 1000,
default = "DWton",
link = "Deadweight tonnage",
},
["g"] = {
_name1 = "gram",
_symbol = "g",
utype = "mass",
scale = 0.001,
prefixes = 1,
default = "oz",
link = "Gram",
},
["gr"] = {
name1 = "grain",
symbol = "gr",
utype = "mass",
scale = 0.00006479891,
default = "g",
link = "Grain (unit)",
},
["Gt"] = {
name1 = "gigatonne",
symbol = "Gt",
utype = "mass",
scale = 1000000000000,
default = "LT ST",
link = "Tonne",
},
["impgalh2o"] = {
name1 = "imperial gallon of water",
name2 = "imperial gallons of water",
symbol = "imp gal H<sub>2</sub>O",
utype = "mass",
scale = 4.5359236999999499,
default = "lb kg",
link = "Imperial gallon",
},
["kt"] = {
name1 = "kilotonne",
symbol = "kt",
utype = "mass",
scale = 1000000,
default = "LT ST",
link = "Tonne",
},
["lb"] = {
name1 = "pound",
symbol = "lb",
utype = "mass",
scale = 0.45359237,
exception= "integer_more_precision",
default = "kg",
subdivs = { ["oz"] = { 16, default = "kg" } },
link = "Pound (mass)",
},
["Lcwt"] = {
name1 = "long hundredweight",
name2 = "long hundredweight",
symbol = "Lcwt",
usename = 1,
utype = "mass",
scale = 50.80234544,
default = "lb",
subdivs = { ["qtr"] = { 4, default = "kg" }, ["st"] = { 8, default = "kg" } },
link = "Hundredweight",
},
["long cwt"] = {
name1 = "long hundredweight",
name2 = "long hundredweight",
symbol = "long cwt",
utype = "mass",
scale = 50.80234544,
default = "lb kg",
subdivs = { ["qtr"] = { 4, default = "kg" } },
link = "Hundredweight",
},
["long qtr"] = {
name1 = "long quarter",
symbol = "long qtr",
utype = "mass",
scale = 12.70058636,
default = "lb kg",
},
["LT"] = {
symbol = "long ton",
usename = 1,
utype = "mass",
scale = 1016.0469088,
default = "t",
subdivs = { ["Lcwt"] = { 20, default = "t", unit = "-Lcwt" } },
},
["lt"] = {
name1 = "long ton",
symbol = "LT",
utype = "mass",
scale = 1016.0469088,
default = "t",
subdivs = { ["Lcwt"] = { 20, default = "t", unit = "-Lcwt" } },
},
["metric ton"] = {
symbol = "metric ton",
usename = 1,
utype = "mass",
scale = 1000,
default = "long ton",
link = "Tonne",
},
["MT"] = {
name1 = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "LT ST",
link = "Tonne",
},
["Mt"] = {
name1 = "megatonne",
symbol = "Mt",
utype = "mass",
scale = 1000000000,
default = "LT ST",
link = "Tonne",
},
["oz"] = {
name1 = "ounce",
symbol = "oz",
utype = "mass",
scale = 0.028349523125,
default = "g",
},
["ozt"] = {
name1 = "troy ounce",
symbol = "ozt",
utype = "mass",
scale = 0.0311034768,
default = "oz g",
},
["pdr"] = {
name1 = "pounder",
symbol = "pdr",
utype = "mass",
scale = 0.45359237,
default = "kg",
link = "Pound (mass)",
},
["qtr"] = {
name1 = "quarter",
symbol = "qtr",
utype = "mass",
scale = 12.70058636,
default = "lb kg",
subdivs = { ["lb"] = { 28, default = "kg" } },
link = "Long quarter",
},
["Scwt"] = {
name1 = "short hundredweight",
name2 = "short hundredweight",
symbol = "Scwt",
usename = 1,
utype = "mass",
scale = 45.359237,
default = "lb",
link = "Hundredweight",
},
["short cwt"] = {
name1 = "short hundredweight",
name2 = "short hundredweight",
symbol = "short cwt",
utype = "mass",
scale = 45.359237,
default = "lb kg",
link = "Hundredweight",
},
["short qtr"] = {
name1 = "short quarter",
symbol = "short qtr",
utype = "mass",
scale = 11.33980925,
default = "lb kg",
},
["ST"] = {
symbol = "short ton",
usename = 1,
utype = "mass",
scale = 907.18474,
default = "t",
subdivs = { ["Scwt"] = { 20, default = "t", unit = "-Scwt" } },
},
["shtn"] = {
name1 = "short ton",
symbol = "sh tn",
utype = "mass",
scale = 907.18474,
default = "t",
},
["shton"] = {
symbol = "ton",
usename = 1,
utype = "mass",
scale = 907.18474,
default = "t",
},
["solar mass"] = {
name1 = "solar mass",
name2 = "solar masses",
symbol = "''M''<sub>☉</sub>",
utype = "mass",
scale = 1.98855e30,
default = "kg",
},
["st"] = {
name1 = "stone",
name2 = "stone",
symbol = "st",
utype = "mass",
scale = 6.35029318,
default = "lb kg",
subdivs = { ["lb"] = { 14, default = "kg lb" } },
link = "Stone (unit)",
},
["t"] = {
name1 = "tonne",
name1_us = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "LT ST",
},
["tonne"] = {
name1 = "tonne",
name1_us = "metric ton",
symbol = "t",
utype = "mass",
scale = 1000,
default = "shton",
},
["troy pound"] = {
symbol = "troy pound",
usename = 1,
utype = "mass",
scale = 0.3732417216,
default = "lb kg",
link = "Troy weight",
},
["usgalh2o"] = {
name1 = "US gallon of water",
name1_us = "U.S. gallon of water",
name2 = "US gallons of water",
name2_us = "U.S. gallons of water",
symbol = "US gal H<sub>2</sub>O",
utype = "mass",
scale = 3.7776215836051126,
default = "lb kg",
link = "United States customary units#Fluid volume",
},
["viss"] = {
name2 = "viss",
symbol = "viss",
utype = "mass",
scale = 1.632932532,
default = "kg",
link = "Myanmar units of measurement#Mass",
},
["billion tonne"] = {
target = "e9t",
},
["kilogram"] = {
target = "kg",
},
["kilotonne"] = {
target = "kt",
},
["lbs"] = {
target = "lb",
},
["lbt"] = {
target = "troy pound",
},
["lcwt"] = {
target = "Lcwt",
},
["long ton"] = {
target = "LT",
},
["mcg"] = {
target = "μg",
},
["million tonne"] = {
target = "e6t",
},
["scwt"] = {
target = "Scwt",
},
["short ton"] = {
target = "ST",
},
["stone"] = {
target = "st",
},
["thousand tonne"] = {
target = "e3t",
},
["tonnes"] = {
target = "t",
},
["kg/kW"] = {
name1 = "kilogram per kilowatt",
name2 = "kilograms per kilowatt",
symbol = "kg/kW",
utype = "mass per unit power",
scale = 0.001,
default = "lb/hp",
link = "Kilowatt",
},
["lb/hp"] = {
name1 = "pound per horsepower",
name2 = "pounds per horsepower",
symbol = "lb/hp",
utype = "mass per unit power",
scale = 0.00060827738784176115,
default = "kg/kW",
link = "Horsepower",
},
["kg/h"] = {
per = { "kg", "h" },
utype = "mass per unit time",
default = "lb/h",
},
["lb/h"] = {
per = { "lb", "h" },
utype = "mass per unit time",
default = "kg/h",
},
["g-mol/d"] = {
name1 = "gram-mole per day",
name2 = "gram-moles per day",
symbol = "g‑mol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["g-mol/h"] = {
name1 = "gram-mole per hour",
name2 = "gram-moles per hour",
symbol = "g‑mol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["g-mol/min"] = {
name1 = "gram-mole per minute",
name2 = "gram-moles per minute",
symbol = "g‑mol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "g-mol/s",
link = "Mole (unit)",
},
["g-mol/s"] = {
name1 = "gram-mole per second",
name2 = "gram-moles per second",
symbol = "g‑mol/s",
utype = "molar rate",
scale = 1,
default = "lb-mol/min",
link = "Mole (unit)",
},
["gmol/d"] = {
name1 = "gram-mole per day",
name2 = "gram-moles per day",
symbol = "gmol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["gmol/h"] = {
name1 = "gram-mole per hour",
name2 = "gram-moles per hour",
symbol = "gmol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["gmol/min"] = {
name1 = "gram-mole per minute",
name2 = "gram-moles per minute",
symbol = "gmol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "gmol/s",
link = "Mole (unit)",
},
["gmol/s"] = {
name1 = "gram-mole per second",
name2 = "gram-moles per second",
symbol = "gmol/s",
utype = "molar rate",
scale = 1,
default = "lbmol/min",
link = "Mole (unit)",
},
["kmol/d"] = {
name1 = "kilomole per day",
name2 = "kilomoles per day",
symbol = "kmol/d",
utype = "molar rate",
scale = 0.011574074074074073,
default = "mmol/s",
link = "Mole (unit)",
},
["kmol/h"] = {
name1 = "kilomole per hour",
name2 = "kilomoles per hour",
symbol = "kmol/h",
utype = "molar rate",
scale = 0.27777777777777779,
default = "mol/s",
link = "Mole (unit)",
},
["kmol/min"] = {
name1 = "kilomole per minute",
name2 = "kilomoles per minute",
symbol = "kmol/min",
utype = "molar rate",
scale = 16.666666666666668,
default = "mol/s",
link = "Kilomole (unit)",
},
["kmol/s"] = {
name1 = "kilomole per second",
name2 = "kilomoles per second",
symbol = "kmol/s",
utype = "molar rate",
scale = 1000,
default = "lb-mol/s",
link = "Mole (unit)",
},
["lb-mol/d"] = {
name1 = "pound-mole per day",
name2 = "pound-moles per day",
symbol = "lb‑mol/d",
utype = "molar rate",
scale = 0.0052499116898148141,
default = "mmol/s",
link = "Pound-mole",
},
["lb-mol/h"] = {
name1 = "pound-mole per hour",
name2 = "pound-moles per hour",
symbol = "lb‑mol/h",
utype = "molar rate",
scale = 0.12599788055555555,
default = "mol/s",
link = "Pound-mole",
},
["lb-mol/min"] = {
name1 = "pound-mole per minute",
name2 = "pound-moles per minute",
symbol = "lb‑mol/min",
utype = "molar rate",
scale = 7.5598728333333334,
default = "mol/s",
link = "Pound-mole",
},
["lb-mol/s"] = {
name1 = "pound-mole per second",
name2 = "pound-moles per second",
symbol = "lb‑mol/s",
utype = "molar rate",
scale = 453.59237,
default = "kmol/s",
link = "Pound-mole",
},
["lbmol/d"] = {
name1 = "pound-mole per day",
name2 = "pound-moles per day",
symbol = "lbmol/d",
utype = "molar rate",
scale = 0.0052499116898148141,
default = "mmol/s",
link = "Pound-mole",
},
["lbmol/h"] = {
name1 = "pound-mole per hour",
name2 = "pound-moles per hour",
symbol = "lbmol/h",
utype = "molar rate",
scale = 0.12599788055555555,
default = "mol/s",
link = "Pound-mole",
},
["lbmol/min"] = {
name1 = "pound-mole per minute",
name2 = "pound-moles per minute",
symbol = "lbmol/min",
utype = "molar rate",
scale = 7.5598728333333334,
default = "mol/s",
link = "Pound-mole",
},
["lbmol/s"] = {
name1 = "pound-mole per second",
name2 = "pound-moles per second",
symbol = "lbmol/s",
utype = "molar rate",
scale = 453.59237,
default = "kmol/s",
link = "Pound-mole",
},
["mmol/s"] = {
name1 = "millimole per second",
name2 = "millimoles per second",
symbol = "mmol/s",
utype = "molar rate",
scale = 0.001,
default = "lb-mol/d",
link = "Mole (unit)",
},
["mol/d"] = {
name1 = "mole per day",
name2 = "moles per day",
symbol = "mol/d",
utype = "molar rate",
scale = 1.1574074074074073e-5,
default = "μmol/s",
link = "Mole (unit)",
},
["mol/h"] = {
name1 = "mole per hour",
name2 = "moles per hour",
symbol = "mol/h",
utype = "molar rate",
scale = 0.00027777777777777778,
default = "mmol/s",
link = "Mole (unit)",
},
["mol/min"] = {
name1 = "mole per minute",
name2 = "moles per minute",
symbol = "mol/min",
utype = "molar rate",
scale = 0.016666666666666666,
default = "mol/s",
link = "Mole (unit)",
},
["mol/s"] = {
name1 = "mole per second",
name2 = "moles per second",
symbol = "mol/s",
utype = "molar rate",
scale = 1,
default = "lb-mol/min",
link = "Mole (unit)",
},
["μmol/s"] = {
name1 = "micromole per second",
name2 = "micromoles per second",
symbol = "μmol/s",
utype = "molar rate",
scale = 0.000001,
default = "lb-mol/d",
link = "Mole (unit)",
},
["umol/s"] = {
target = "μmol/s",
},
["/acre"] = {
name1 = "per acre",
name2 = "per acre",
symbol = "/acre",
utype = "per unit area",
scale = 0.00024710538146716532,
default = "/ha",
link = "Acre",
},
["/ha"] = {
name1 = "per hectare",
name2 = "per hectare",
symbol = "/ha",
utype = "per unit area",
scale = 100e-6,
default = "/acre",
link = "Hectare",
},
["/sqcm"] = {
name1 = "per square centimetre",
name1_us = "per square centimeter",
name2 = "per square centimetre",
name2_us = "per square centimeter",
symbol = "/cm<sup>2</sup>",
utype = "per unit area",
scale = 1e4,
default = "/sqin",
link = "Square centimetre",
},
["/sqin"] = {
name1 = "per square inch",
name2 = "per square inch",
symbol = "/in<sup>2</sup>",
utype = "per unit area",
scale = 1550.0031000062002,
default = "/sqcm",
link = "Square inch",
},
["/sqkm"] = {
name1 = "per square kilometre",
name1_us = "per square kilometer",
name2 = "per square kilometre",
name2_us = "per square kilometer",
symbol = "/km<sup>2</sup>",
utype = "per unit area",
scale = 1e-6,
default = "/sqmi",
link = "Square kilometre",
},
["/sqmi"] = {
name1 = "per square mile",
name2 = "per square mile",
symbol = "/sq mi",
utype = "per unit area",
scale = 3.8610215854244582e-7,
default = "/sqkm",
link = "Square mile",
},
["PD/acre"] = {
name1 = "inhabitant per acre",
name2 = "inhabitants per acre",
symbol = "/acre",
utype = "per unit area",
scale = 0.00024710538146716532,
default = "PD/ha",
link = "Acre",
},
["PD/ha"] = {
name1 = "inhabitant per hectare",
name2 = "inhabitants per hectare",
symbol = "/ha",
utype = "per unit area",
scale = 100e-6,
default = "PD/acre",
link = "Hectare",
},
["PD/sqkm"] = {
name1 = "inhabitant per square kilometre",
name1_us = "inhabitant per square kilometer",
name2 = "inhabitants per square kilometre",
name2_us = "inhabitants per square kilometer",
symbol = "/km<sup>2</sup>",
utype = "per unit area",
scale = 1e-6,
default = "PD/sqmi",
link = "Square kilometre",
},
["PD/sqmi"] = {
name1 = "inhabitant per square mile",
name2 = "inhabitants per square mile",
symbol = "/sq mi",
utype = "per unit area",
scale = 3.8610215854244582e-7,
default = "PD/sqkm",
link = "Square mile",
},
["/cm2"] = {
target = "/sqcm",
},
["/in2"] = {
target = "/sqin",
},
["/km2"] = {
target = "/sqkm",
},
["pd/acre"] = {
target = "PD/acre",
},
["pd/ha"] = {
target = "PD/ha",
},
["PD/km2"] = {
target = "PD/sqkm",
},
["pd/km2"] = {
target = "PD/sqkm",
},
["PD/km²"] = {
target = "PD/sqkm",
},
["pd/sqkm"] = {
target = "PD/sqkm",
},
["pd/sqmi"] = {
target = "PD/sqmi",
},
["/l"] = {
name1 = "per litre",
name1_us = "per liter",
name2 = "per litre",
name2_us = "per liter",
symbol = "/l",
utype = "per unit volume",
scale = 1000,
default = "/usgal",
link = "Litre",
},
["/USgal"] = {
name1 = "per gallon",
name2 = "per gallon",
symbol = "/gal",
utype = "per unit volume",
scale = 264.172052,
default = "/l",
link = "US gallon",
customary= 2,
},
["/usgal"] = {
target = "/USgal",
},
["bhp"] = {
name1 = "brake horsepower",
name2 = "brake horsepower",
symbol = "bhp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Brake horsepower",
},
["Cal/d"] = {
name1 = "large calorie per day",
name2 = "large calories per day",
symbol = "Cal/d",
utype = "power",
scale = 0.048425925925925928,
default = "kJ/d",
link = "Calorie",
},
["Cal/h"] = {
name1 = "large calorie per hour",
name2 = "large calories per hour",
symbol = "Cal/h",
utype = "power",
scale = 1.1622222222222223,
default = "kJ/h",
link = "Calorie",
},
["cal/h"] = {
name1 = "calorie per hour",
name2 = "calories per hour",
symbol = "cal/h",
utype = "power",
scale = 0.0011622222222222223,
default = "W",
link = "Calorie",
},
["CV"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "CV",
utype = "power",
scale = 735.49875,
default = "kW",
},
["hk"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "hk",
utype = "power",
scale = 735.49875,
default = "kW",
},
["hp"] = {
name1 = "horsepower",
name2 = "horsepower",
symbol = "hp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
},
["hp-electric"] = {
name1 = "electric horsepower",
name2 = "electric horsepower",
symbol = "hp",
utype = "power",
scale = 746,
default = "kW",
link = "Horsepower#Electrical horsepower",
},
["hp-electrical"] = {
name1 = "electrical horsepower",
name2 = "electrical horsepower",
symbol = "hp",
utype = "power",
scale = 746,
default = "kW",
link = "Horsepower#Electrical horsepower",
},
["hp-metric"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "hp",
utype = "power",
scale = 735.49875,
default = "kW",
},
["ihp"] = {
name1 = "indicated horsepower",
name2 = "indicated horsepower",
symbol = "ihp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Indicated horsepower",
},
["kcal/h"] = {
name1 = "kilocalorie per hour",
name2 = "kilocalories per hour",
symbol = "kcal/h",
utype = "power",
scale = 1.1622222222222223,
default = "kW",
link = "Calorie",
},
["kJ/d"] = {
name1 = "kilojoule per day",
name2 = "kilojoules per day",
symbol = "kJ/d",
utype = "power",
scale = 0.011574074074074073,
default = "Cal/d",
link = "Kilojoule",
},
["kJ/h"] = {
name1 = "kilojoule per hour",
name2 = "kilojoules per hour",
symbol = "kJ/h",
utype = "power",
scale = 0.27777777777777779,
default = "W",
link = "Kilojoule",
},
["PS"] = {
name1 = "metric horsepower",
name2 = "metric horsepower",
symbol = "PS",
utype = "power",
scale = 735.49875,
default = "kW",
},
["shp"] = {
name1 = "shaft horsepower",
name2 = "shaft horsepower",
symbol = "shp",
utype = "power",
scale = 745.69987158227022,
default = "kW",
link = "Horsepower#Shaft horsepower",
},
["W"] = {
_name1 = "watt",
_symbol = "W",
utype = "power",
scale = 1,
prefixes = 1,
default = "hp",
link = "Watt",
},
["BTU/h"] = {
per = { "BTU", "h" },
utype = "power",
default = "W",
},
["Btu/h"] = {
per = { "Btu", "h" },
utype = "power",
default = "W",
},
["BHP"] = {
target = "bhp",
},
["btu/h"] = {
target = "BTU/h",
},
["HP"] = {
target = "hp",
},
["Hp"] = {
target = "hp",
},
["hp-mechanical"] = {
target = "hp",
},
["IHP"] = {
target = "ihp",
},
["SHP"] = {
target = "shp",
},
["whp"] = {
target = "hp",
},
["hp/lb"] = {
name1 = "horsepower per pound",
name2 = "horsepower per pound",
symbol = "hp/lb",
utype = "power per unit mass",
scale = 1643.986806,
default = "kW/kg",
link = "Power-to-weight ratio",
},
["hp/LT"] = {
name1 = "horsepower per long ton",
name2 = "horsepower per long ton",
symbol = "hp/LT",
utype = "power per unit mass",
scale = 0.73392268125000004,
default = "kW/t",
link = "Power-to-weight ratio",
},
["hp/ST"] = {
name1 = "horsepower per short ton",
name2 = "horsepower per short ton",
symbol = "hp/ST",
utype = "power per unit mass",
scale = 0.821993403,
default = "kW/t",
link = "Power-to-weight ratio",
},
["hp/t"] = {
name1 = "horsepower per tonne",
name2 = "horsepower per tonne",
symbol = "hp/t",
utype = "power per unit mass",
scale = 0.74569987158227022,
default = "kW/t",
link = "Power-to-weight ratio",
},
["kW/kg"] = {
name1 = "kilowatt per kilogram",
name2 = "kilowatts per kilogram",
symbol = "kW/kg",
utype = "power per unit mass",
scale = 1000,
default = "hp/lb",
link = "Power-to-weight ratio",
},
["kW/t"] = {
name1 = "kilowatt per tonne",
name2 = "kilowatts per tonne",
symbol = "kW/t",
utype = "power per unit mass",
scale = 1,
default = "PS/t",
link = "Power-to-weight ratio",
},
["PS/t"] = {
name1 = "metric horsepower per tonne",
name2 = "metric horsepower per tonne",
symbol = "PS/t",
utype = "power per unit mass",
scale = 0.73549875,
default = "kW/t",
link = "Power-to-weight ratio",
},
["shp/lb"] = {
name1 = "shaft horsepower per pound",
name2 = "shaft horsepower per pound",
symbol = "shp/lb",
utype = "power per unit mass",
scale = 1643.986806,
default = "kW/kg",
link = "Power-to-weight ratio",
},
["hp/tonne"] = {
target = "hp/t",
symbol = "hp/tonne",
default = "kW/tonne",
},
["kW/tonne"] = {
target = "kW/t",
symbol = "kW/tonne",
},
["-lb/in2"] = {
name1 = "pound per square inch",
name2 = "pounds per square inch",
symbol = "lb/in<sup>2</sup>",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa kgf/cm2",
},
["atm"] = {
name1 = "standard atmosphere",
symbol = "atm",
utype = "pressure",
scale = 101325,
default = "kPa",
link = "Atmosphere (unit)",
},
["Ba"] = {
name1 = "barye",
symbol = "Ba",
utype = "pressure",
scale = 0.1,
default = "Pa",
},
["bar"] = {
symbol = "bar",
utype = "pressure",
scale = 100000,
default = "kPa",
link = "Bar (unit)",
},
["dbar"] = {
name1 = "decibar",
symbol = "dbar",
utype = "pressure",
scale = 10000,
default = "kPa",
link = "Bar (unit)",
},
["inHg"] = {
name1 = "inch of mercury",
name2 = "inches of mercury",
symbol = "inHg",
utype = "pressure",
scale = 3386.388640341,
default = "kPa",
},
["kBa"] = {
name1 = "kilobarye",
symbol = "kBa",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Barye",
},
["kg-f/cm2"] = {
name1 = "kilogram-force per square centimetre",
name1_us = "kilogram-force per square centimeter",
name2 = "kilograms-force per square centimetre",
name2_us = "kilograms-force per square centimeter",
symbol = "kg<sub>f</sub>/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["kg/cm2"] = {
name1 = "kilogram per square centimetre",
name1_us = "kilogram per square centimeter",
name2 = "kilograms per square centimetre",
name2_us = "kilograms per square centimeter",
symbol = "kg/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["kgf/cm2"] = {
name1 = "kilogram-force per square centimetre",
name1_us = "kilogram-force per square centimeter",
name2 = "kilograms-force per square centimetre",
name2_us = "kilograms-force per square centimeter",
symbol = "kgf/cm<sup>2</sup>",
utype = "pressure",
scale = 98066.5,
default = "psi",
link = "Kilogram-force",
},
["ksi"] = {
name1 = "kilopound per square inch",
name2 = "kilopounds per square inch",
symbol = "ksi",
utype = "pressure",
scale = 6894757.2931683613,
default = "MPa",
link = "Pound per square inch",
},
["lbf/in2"] = {
name1 = "pound-force per square inch",
name2 = "pounds-force per square inch",
symbol = "lbf/in<sup>2</sup>",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa kgf/cm2",
},
["mb"] = {
name1 = "millibar",
symbol = "mb",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Bar (unit)",
},
["mbar"] = {
name1 = "millibar",
symbol = "mbar",
utype = "pressure",
scale = 100,
default = "hPa",
link = "Bar (unit)",
},
["mmHg"] = {
name1 = "millimetre of mercury",
name1_us = "millimeter of mercury",
name2 = "millimetres of mercury",
name2_us = "millimeters of mercury",
symbol = "mmHg",
utype = "pressure",
scale = 133.322387415,
default = "kPa",
},
["Pa"] = {
_name1 = "pascal",
_symbol = "Pa",
utype = "pressure",
scale = 1,
prefixes = 1,
default = "psi",
link = "Pascal (unit)",
},
["psf"] = {
name1 = "pound per square foot",
name2 = "pounds per square foot",
symbol = "psf",
utype = "pressure",
scale = 47.880258980335839,
default = "kPa",
link = "Pound per square inch",
},
["psi"] = {
name1 = "pound per square inch",
name2 = "pounds per square inch",
symbol = "psi",
utype = "pressure",
scale = 6894.7572931683608,
default = "kPa",
},
["Torr"] = {
name1 = "torr",
symbol = "Torr",
utype = "pressure",
scale = 133.32236842105263,
default = "kPa",
},
["N/cm2"] = {
per = { "N", "cm2" },
utype = "pressure",
default = "psi",
},
["N/m2"] = {
per = { "N", "m2" },
utype = "pressure",
default = "psi",
},
["g/cm2"] = {
per = { "g", "cm2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["g/m2"] = {
per = { "g", "m2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["kg/ha"] = {
per = { "kg", "ha" },
utype = "pressure",
default = "lb/acre",
multiplier= 9.80665,
},
["kg/m2"] = {
per = { "kg", "m2" },
utype = "pressure",
default = "lb/sqft",
multiplier= 9.80665,
},
["lb/1000sqft"] = {
per = { "lb", "1000sqft" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["lb/acre"] = {
per = { "lb", "acre" },
utype = "pressure",
default = "kg/ha",
multiplier= 9.80665,
},
["lb/sqft"] = {
per = { "lb", "sqft" },
utype = "pressure",
default = "kg/m2",
multiplier= 9.80665,
},
["lb/sqyd"] = {
per = { "lb", "sqyd" },
utype = "pressure",
default = "kg/m2",
multiplier= 9.80665,
},
["LT/acre"] = {
per = { "LT", "acre" },
utype = "pressure",
default = "t/ha",
multiplier= 9.80665,
},
["MT/ha"] = {
per = { "MT", "ha" },
utype = "pressure",
default = "LT/acre ST/acre",
multiplier= 9.80665,
},
["oz/sqft"] = {
per = { "oz", "sqft" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["oz/sqyd"] = {
per = { "oz", "sqyd" },
utype = "pressure",
default = "g/m2",
multiplier= 9.80665,
},
["ST/acre"] = {
per = { "ST", "acre" },
utype = "pressure",
default = "t/ha",
multiplier= 9.80665,
},
["t/ha"] = {
per = { "t", "ha" },
utype = "pressure",
default = "LT/acre ST/acre",
multiplier= 9.80665,
},
["tonne/acre"] = {
per = { "tonne", "acre" },
utype = "pressure",
default = "tonne/ha",
multiplier= 9.80665,
},
["tonne/ha"] = {
per = { "tonne", "ha" },
utype = "pressure",
default = "tonne/acre",
multiplier= 9.80665,
},
["kgfpsqcm"] = {
target = "kgf/cm2",
},
["kgpsqcm"] = {
target = "kg/cm2",
},
["kN/m2"] = {
target = "kPa",
},
["lb/in2"] = {
target = "lbf/in2",
},
["torr"] = {
target = "Torr",
},
["Bq"] = {
_name1 = "becquerel",
_symbol = "Bq",
utype = "radioactivity",
scale = 1,
prefixes = 1,
default = "pCi",
link = "Becquerel",
},
["Ci"] = {
_name1 = "curie",
_symbol = "Ci",
utype = "radioactivity",
scale = 3.7e10,
prefixes = 1,
default = "GBq",
link = "Curie (unit)",
},
["Rd"] = {
_name1 = "rutherford",
_symbol = "Rd",
utype = "radioactivity",
scale = 1e6,
prefixes = 1,
default = "MBq",
link = "Rutherford (unit)",
},
["cm/h"] = {
name1 = "centimetre per hour",
name1_us = "centimeter per hour",
name2 = "centimetres per hour",
name2_us = "centimeters per hour",
symbol = "cm/h",
utype = "speed",
scale = 2.7777777777777775e-6,
default = "in/h",
link = "Metre per second",
},
["cm/s"] = {
name1 = "centimetre per second",
name1_us = "centimeter per second",
name2 = "centimetres per second",
name2_us = "centimeters per second",
symbol = "cm/s",
utype = "speed",
scale = 0.01,
default = "in/s",
link = "Metre per second",
},
["cm/year"] = {
name1 = "centimetre per year",
name1_us = "centimeter per year",
name2 = "centimetres per year",
name2_us = "centimeters per year",
symbol = "cm/year",
utype = "speed",
scale = 3.168873850681143e-10,
default = "in/year",
link = "Orders of magnitude (speed)",
},
["foot/s"] = {
name1 = "foot per second",
name2 = "foot per second",
symbol = "ft/s",
utype = "speed",
scale = 0.3048,
default = "m/s",
},
["ft/min"] = {
name1 = "foot per minute",
name2 = "feet per minute",
symbol = "ft/min",
utype = "speed",
scale = 0.00508,
default = "m/min",
link = "Feet per second",
},
["ft/s"] = {
name1 = "foot per second",
name2 = "feet per second",
symbol = "ft/s",
utype = "speed",
scale = 0.3048,
default = "m/s",
link = "Feet per second",
},
["furlong per fortnight"] = {
name2 = "furlongs per fortnight",
symbol = "furlong per fortnight",
usename = 1,
utype = "speed",
scale = 0.00016630952380952381,
default = "km/h mph",
link = "FFF system",
},
["in/h"] = {
name1 = "inch per hour",
name2 = "inches per hour",
symbol = "in/h",
utype = "speed",
scale = 7.0555555555555559e-6,
default = "cm/h",
link = "Inch",
},
["in/s"] = {
name1 = "inch per second",
name2 = "inches per second",
symbol = "in/s",
utype = "speed",
scale = 0.0254,
default = "cm/s",
link = "Inch",
},
["in/year"] = {
name1 = "inch per year",
name2 = "inches per year",
symbol = "in/year",
utype = "speed",
scale = 8.0489395807301024e-10,
default = "cm/year",
link = "Orders of magnitude (speed)",
},
["isp"] = {
name1 = "second",
symbol = "s",
utype = "speed",
scale = 9.80665,
default = "km/s",
link = "Specific impulse",
},
["km/d"] = {
name1 = "kilometre per day",
name1_us = "kilometer per day",
name2 = "kilometres per day",
name2_us = "kilometers per day",
symbol = "km/d",
utype = "speed",
scale = 1.1574074074074074e-2,
default = "mi/d",
link = "Orders of magnitude (speed)",
},
["km/h"] = {
name1 = "kilometre per hour",
name1_us = "kilometer per hour",
name2 = "kilometres per hour",
name2_us = "kilometers per hour",
symbol = "km/h",
utype = "speed",
scale = 0.27777777777777779,
default = "mph",
link = "Kilometres per hour",
},
["km/s"] = {
name1 = "kilometre per second",
name1_us = "kilometer per second",
name2 = "kilometres per second",
name2_us = "kilometers per second",
symbol = "km/s",
utype = "speed",
scale = 1000,
default = "mi/s",
link = "Metre per second",
},
["kn"] = {
name1 = "knot",
symbol = "kn",
utype = "speed",
scale = 0.51444444444444448,
default = "km/h mph",
link = "Knot (unit)",
},
["kNs/kg"] = {
name2 = "kN‑s/kg",
symbol = "kN‑s/kg",
utype = "speed",
scale = 1000,
default = "isp",
link = "Specific impulse",
},
["m/min"] = {
name1 = "metre per minute",
name1_us = "meter per minute",
name2 = "metres per minute",
name2_us = "meters per minute",
symbol = "m/min",
utype = "speed",
scale = 0.016666666666666666,
default = "ft/min",
link = "Metre per second",
},
["m/s"] = {
name1 = "metre per second",
name1_us = "meter per second",
name2 = "metres per second",
name2_us = "meters per second",
symbol = "m/s",
utype = "speed",
scale = 1,
default = "ft/s",
},
["Mach"] = {
name2 = "Mach",
symbol = "Mach",
utype = "speed",
builtin = "mach",
scale = 0,
iscomplex= true,
default = "km/h mph",
link = "Mach number",
},
["mi/d"] = {
name1 = "mile per day",
name2 = "miles per day",
symbol = "mi/d",
utype = "speed",
scale = 1.8626666666666667e-2,
default = "km/d",
link = "Orders of magnitude (speed)",
},
["mi/s"] = {
name1 = "mile per second",
name2 = "miles per second",
symbol = "mi/s",
utype = "speed",
scale = 1609.344,
default = "km/s",
link = "Mile",
},
["mm/h"] = {
name1 = "millimetre per hour",
name1_us = "millimeter per hour",
name2 = "millimetres per hour",
name2_us = "millimeters per hour",
symbol = "mm/h",
utype = "speed",
scale = 2.7777777777777781e-7,
default = "in/h",
link = "Metre per second",
},
["mph"] = {
name1 = "mile per hour",
name2 = "miles per hour",
symbol = "mph",
utype = "speed",
scale = 0.44704,
default = "km/h",
link = "Miles per hour",
},
["Ns/kg"] = {
name2 = "N‑s/kg",
symbol = "N‑s/kg",
utype = "speed",
scale = 1,
default = "isp",
link = "Specific impulse",
},
["si tsfc"] = {
name2 = "g/(kN⋅s)",
symbol = "g/(kN⋅s)",
utype = "speed",
scale = 9.9999628621379242e-7,
invert = -1,
iscomplex= true,
default = "tsfc",
link = "Thrust specific fuel consumption",
},
["tsfc"] = {
name2 = "lb/(lbf⋅h)",
symbol = "lb/(lbf⋅h)",
utype = "speed",
scale = 2.832545036049801e-5,
invert = -1,
iscomplex= true,
default = "si tsfc",
link = "Thrust specific fuel consumption",
},
["cm/y"] = {
target = "cm/year",
},
["cm/yr"] = {
target = "cm/year",
},
["in/y"] = {
target = "in/year",
},
["in/yr"] = {
target = "in/year",
},
["knot"] = {
target = "kn",
},
["knots"] = {
target = "kn",
},
["kph"] = {
target = "km/h",
},
["mi/h"] = {
target = "mph",
},
["mm/s"] = {
per = { "mm", "s" },
utype = "speed",
default = "in/s",
link = "Metre per second",
},
["C"] = {
name1 = "degree Celsius",
name2 = "degrees Celsius",
symbol = "°C",
usesymbol= 1,
utype = "temperature",
scale = 1,
offset = -273.15,
iscomplex= true,
istemperature= true,
default = "F",
link = "Celsius",
},
["F"] = {
name1 = "degree Fahrenheit",
name2 = "degrees Fahrenheit",
symbol = "°F",
usesymbol= 1,
utype = "temperature",
scale = 0.55555555555555558,
offset = 32-273.15*(9/5),
iscomplex= true,
istemperature= true,
default = "C",
link = "Fahrenheit",
},
["K"] = {
_name1 = "kelvin",
_symbol = "K",
usesymbol= 1,
utype = "temperature",
scale = 1,
offset = 0,
iscomplex= true,
istemperature= true,
prefixes = 1,
default = "C F",
link = "Kelvin",
},
["keVT"] = {
name1 = "kiloelectronvolt",
symbol = "keV",
utype = "temperature",
scale = 11.604505e6,
offset = 0,
iscomplex= true,
default = "MK",
link = "Electronvolt",
},
["R"] = {
name1 = "degree Rankine",
name2 = "degrees Rankine",
symbol = "°R",
usesymbol= 1,
utype = "temperature",
scale = 0.55555555555555558,
offset = 0,
iscomplex= true,
istemperature= true,
default = "K F C",
link = "Rankine scale",
},
["Celsius"] = {
target = "C",
},
["°C"] = {
target = "C",
},
["°F"] = {
target = "F",
},
["°R"] = {
target = "R",
},
["C-change"] = {
name1 = "degree Celsius change",
name2 = "degrees Celsius change",
symbol = "°C",
usesymbol= 1,
utype = "temperature change",
scale = 1,
default = "F-change",
link = "Celsius",
},
["F-change"] = {
name1 = "degree Fahrenheit change",
name2 = "degrees Fahrenheit change",
symbol = "°F",
usesymbol= 1,
utype = "temperature change",
scale = 0.55555555555555558,
default = "C-change",
link = "Fahrenheit",
},
["K-change"] = {
name1 = "kelvin change",
name2 = "kelvins change",
symbol = "K",
usesymbol= 1,
utype = "temperature change",
scale = 1,
default = "F-change",
link = "Kelvin",
},
["°C-change"] = {
target = "C-change",
},
["°F-change"] = {
target = "F-change",
},
["century"] = {
name1 = "century",
name2 = "centuries",
symbol = "ha",
utype = "time",
scale = 3155760000,
default = "Gs",
},
["d"] = {
name1 = "day",
symbol = "d",
utype = "time",
scale = 86400,
default = "ks",
},
["decade"] = {
name1 = "decade",
symbol = "daa",
utype = "time",
scale = 315576000,
default = "Ms",
},
["dog year"] = {
name1 = "dog year",
symbol = "dog yr",
utype = "time",
scale = 220903200,
default = "years",
link = "List of unusual units of measurement#Dog year",
},
["fortnight"] = {
symbol = "fortnight",
usename = 1,
utype = "time",
scale = 1209600,
default = "week",
},
["h"] = {
name1 = "hour",
symbol = "h",
utype = "time",
scale = 3600,
default = "ks",
},
["long billion year"] = {
name1 = "billion years",
name2 = "billion years",
symbol = "Ta",
utype = "time",
scale = 31557600000000000000,
default = "Es",
link = "Annum",
},
["millennium"] = {
name1 = "millennium",
name2 = "millennia",
symbol = "ka",
utype = "time",
scale = 31557600000,
default = "Gs",
},
["milliard year"] = {
name1 = "milliard years",
name2 = "milliard years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["million year"] = {
name1 = "million years",
name2 = "million years",
symbol = "Ma",
utype = "time",
scale = 31557600000000,
default = "Ts",
link = "Annum",
},
["min"] = {
name1 = "minute",
symbol = "min",
utype = "time",
scale = 60,
default = "s",
},
["month"] = {
symbol = "month",
usename = 1,
utype = "time",
scale = 2629800,
default = "Ms",
},
["months"] = {
name1 = "month",
symbol = "mo",
utype = "time",
scale = 2629800,
default = "year",
},
["s"] = {
_name1 = "second",
_symbol = "s",
utype = "time",
scale = 1,
prefixes = 1,
default = "min",
link = "Second",
},
["short billion year"] = {
name1 = "billion years",
name2 = "billion years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["short trillion year"] = {
name1 = "trillion years",
name2 = "trillion years",
symbol = "Ta",
utype = "time",
scale = 31557600000000000000,
default = "Es",
link = "Annum",
},
["thousand million year"] = {
name1 = "thousand million years",
name2 = "thousand million years",
symbol = "Ga",
utype = "time",
scale = 31557600000000000,
default = "Ps",
link = "Annum",
},
["wk"] = {
symbol = "week",
usename = 1,
utype = "time",
scale = 604800,
default = "Ms",
},
["year"] = {
name1 = "year",
symbol = "a",
utype = "time",
scale = 31557600,
default = "Ms",
link = "Annum",
},
["years"] = {
name1 = "year",
symbol = "yr",
utype = "time",
scale = 31557600,
default = "Ms",
link = "Annum",
},
["byr"] = {
target = "short billion year",
},
["day"] = {
target = "d",
},
["days"] = {
target = "d",
},
["dog yr"] = {
target = "dog year",
},
["Gyr"] = {
target = "thousand million year",
},
["hour"] = {
target = "h",
},
["hours"] = {
target = "h",
},
["kMyr"] = {
target = "thousand million year",
},
["kmyr"] = {
target = "thousand million year",
},
["kyr"] = {
target = "millennium",
},
["long byr"] = {
target = "long billion year",
},
["minute"] = {
target = "min",
},
["minutes"] = {
target = "min",
},
["mth"] = {
target = "month",
},
["Myr"] = {
target = "million year",
},
["myr"] = {
target = "million year",
},
["second"] = {
target = "s",
},
["seconds"] = {
target = "s",
},
["tmyr"] = {
target = "thousand million year",
},
["tryr"] = {
target = "short trillion year",
},
["tyr"] = {
target = "millennium",
},
["week"] = {
target = "wk",
},
["weeks"] = {
target = "wk",
},
["yr"] = {
target = "year",
},
["kg.m"] = {
name1 = "kilogram metre",
name1_us = "kilogram meter",
symbol = "kg⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbft",
link = "Kilogram metre (torque)",
},
["kgf.m"] = {
name1 = "kilogram force-metre",
name1_us = "kilogram force-meter",
symbol = "kgf⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["kgm"] = {
name1 = "kilogram metre",
name1_us = "kilogram meter",
symbol = "kg⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["kpm"] = {
name1 = "kilopond metre",
name1_us = "kilopond meter",
symbol = "kp⋅m",
utype = "torque",
scale = 9.80665,
default = "Nm lbft",
link = "Kilogram metre (torque)",
},
["lb-fft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "ft⋅lb<sub>f</sub>",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lb.ft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "lb⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lb.in"] = {
name1 = "pound force-inch",
symbol = "lb⋅in",
utype = "torque",
scale = 0.1129848290276167,
default = "mN.m",
link = "Pound-foot (torque)",
},
["lbfft"] = {
name1 = "pound force-foot",
name2 = "pound force-feet",
symbol = "lbf⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["lbft"] = {
name1 = "pound-foot",
name2 = "pound-feet",
symbol = "lb⋅ft",
utype = "torque",
scale = 1.3558179483314004,
default = "Nm",
link = "Pound-foot (torque)",
},
["m.kg-f"] = {
name1 = "metre kilogram-force",
name1_us = "meter kilogram-force",
name2 = "metre kilograms-force",
name2_us = "meter kilograms-force",
symbol = "m⋅kg<sub>f</sub>",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["m.kgf"] = {
name1 = "metre kilogram-force",
name1_us = "meter kilogram-force",
name2 = "metre kilograms-force",
name2_us = "meter kilograms-force",
symbol = "m⋅kgf",
utype = "torque",
scale = 9.80665,
default = "Nm lbfft",
link = "Kilogram metre (torque)",
},
["mN.m"] = {
name1 = "millinewton-metre",
name1_us = "millinewton-meter",
symbol = "mN⋅m",
utype = "torque",
scale = 0.001,
default = "lb.in",
link = "Newton-metre",
},
["Nm"] = {
_name1 = "newton-metre",
_name1_us= "newton-meter",
_symbol = "N⋅m",
utype = "torque",
alttype = "energy",
scale = 1,
prefixes = 1,
default = "lbfft",
link = "Newton-metre",
},
["kN/m"] = {
per = { "kN", "-m-stiff" },
utype = "torque",
default = "lbf/in",
},
["lbf/in"] = {
per = { "lbf", "-in-stiff" },
utype = "torque",
default = "kN/m",
},
["lb-f.ft"] = {
target = "lb-fft",
},
["lbf.ft"] = {
target = "lbfft",
},
["lbf·ft"] = {
target = "lbfft",
},
["lb·ft"] = {
target = "lb.ft",
},
["mkg-f"] = {
target = "m.kg-f",
},
["mkgf"] = {
target = "m.kgf",
},
["N.m"] = {
target = "Nm",
},
["N·m"] = {
target = "Nm",
},
["ton-mile"] = {
symbol = "ton-mile",
usename = 1,
utype = "transportation",
scale = 1.4599723182105602,
default = "tkm",
},
["tkm"] = {
name1 = "tonne-kilometre",
name1_us = "tonne-kilometer",
symbol = "tkm",
utype = "transportation",
scale = 1,
default = "ton-mile",
},
["-12USoz(mL)serve"] = {
name1_us = "12 U.S. fl oz (355 mL) serving",
symbol = "12 US fl oz (355 mL) serving",
sym_us = "12 U.S. fl oz (355 mL) serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "mL",
link = "Beverage can#Standard sizes",
},
["-12USoz(ml)serve"] = {
name1_us = "12 U.S. fl oz (355 ml) serving",
symbol = "12 US fl oz (355 ml) serving",
sym_us = "12 U.S. fl oz (355 ml) serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "ml",
link = "Beverage can#Standard sizes",
},
["-12USozserve"] = {
name1_us = "12 U.S. fl oz serving",
symbol = "12 US fl oz serving",
sym_us = "12 U.S. fl oz serving",
utype = "volume",
scale = 0.00035488235475000004,
default = "mL",
link = "Beverage can#Standard sizes",
},
["acre-foot"] = {
name1 = "acre-foot",
name2 = "acre-foot",
symbol = "acre⋅ft",
utype = "volume",
scale = 1233.48183754752,
default = "m3",
},
["acre-ft"] = {
name1 = "acre-foot",
name2 = "acre-feet",
symbol = "acre⋅ft",
utype = "volume",
scale = 1233.48183754752,
default = "m3",
},
["AUtbsp"] = {
name1 = "Australian tablespoon",
symbol = "AU tbsp",
utype = "volume",
scale = 0.000020,
default = "ml",
},
["Bcuft"] = {
name1 = "billion cubic foot",
name2 = "billion cubic feet",
symbol = "billion cu ft",
utype = "volume",
scale = 28316846.592,
default = "Gl",
link = "Cubic foot",
},
["bdft"] = {
name1 = "board foot",
name2 = "board feet",
symbol = "bd ft",
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["board feet"] = {
name2 = "board feet",
symbol = "board foot",
usename = 1,
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["board foot"] = {
name2 = "board foot",
symbol = "board foot",
usename = 1,
utype = "volume",
scale = 0.0023597372167,
default = "m3",
},
["cc"] = {
name1 = "cubic centimetre",
name1_us = "cubic centimeter",
symbol = "cc",
utype = "volume",
scale = 0.000001,
default = "cuin",
},
["CID"] = {
name1 = "cubic inch",
name2 = "cubic inches",
symbol = "cu in",
utype = "volume",
scale = 0.000016387064,
default = "cc",
link = "Cubic inch#Engine displacement",
},
["cord"] = {
symbol = "cord",
utype = "volume",
scale = 3.624556363776,
default = "m3",
link = "Cord (unit)",
},
["cufoot"] = {
name1 = "cubic foot",
name2 = "cubic foot",
symbol = "cu ft",
utype = "volume",
scale = 0.028316846592,
default = "m3",
},
["cuft"] = {
name1 = "cubic foot",
name2 = "cubic feet",
symbol = "cu ft",
utype = "volume",
scale = 0.028316846592,
default = "m3",
},
["cuin"] = {
name1 = "cubic inch",
name2 = "cubic inches",
symbol = "cu in",
utype = "volume",
scale = 0.000016387064,
default = "cm3",
},
["cumi"] = {
name1 = "cubic mile",
symbol = "cu mi",
utype = "volume",
scale = 4168181825.440579584,
default = "km3",
},
["cuyd"] = {
name1 = "cubic yard",
symbol = "cu yd",
utype = "volume",
scale = 0.764554857984,
default = "m3",
},
["firkin"] = {
symbol = "firkin",
usename = 1,
utype = "volume",
scale = 0.04091481,
default = "l impgal USgal",
link = "Firkin (unit)",
},
["foot3"] = {
target = "cufoot",
},
["Goilbbl"] = {
name1 = "billion barrels",
name2 = "billion barrels",
symbol = "Gbbl",
utype = "volume",
scale = 158987294.928,
default = "v * 1.58987294928 < 10 ! e6 ! e9 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["gr water"] = {
name1 = "grains water",
name2 = "grains water",
symbol = "gr H<sub>2</sub>O",
utype = "volume",
scale = 0.00000006479891,
default = "cm3",
link = "Grain (unit)",
},
["grt"] = {
name1 = "gross register ton",
symbol = "grt",
utype = "volume",
scale = 2.8316846592,
default = "m3",
link = "Gross register tonnage",
},
["impbbl"] = {
name1 = "imperial barrel",
symbol = "imp bbl",
utype = "volume",
scale = 0.16365924,
default = "l impgal USgal",
link = "Barrel (unit)",
},
["impbsh"] = {
name1 = "imperial bushel",
symbol = "imp bsh",
utype = "volume",
scale = 0.03636872,
default = "l impgal USdrygal",
},
["impbu"] = {
name1 = "imperial bushel",
symbol = "imp bu",
utype = "volume",
scale = 0.03636872,
default = "m3",
},
["impgal"] = {
name1 = "imperial gallon",
symbol = "imp gal",
utype = "volume",
scale = 0.00454609,
default = "l USgal",
},
["impgi"] = {
name1 = "gill",
symbol = "gi",
utype = "volume",
scale = 0.0001420653125,
default = "ml USoz",
link = "Gill (unit)",
},
["impkenning"] = {
name1 = "imperial kenning",
symbol = "kenning",
utype = "volume",
scale = 0.01818436,
default = "l USdrygal",
link = "Kenning (unit)",
},
["impoz"] = {
name1 = "imperial fluid ounce",
symbol = "imp fl oz",
utype = "volume",
scale = 0.0000284130625,
default = "ml USoz",
},
["imppk"] = {
name1 = "imperial peck",
symbol = "pk",
utype = "volume",
scale = 0.00909218,
default = "l USdrygal",
link = "Peck",
},
["imppt"] = {
name1 = "imperial pint",
symbol = "imp pt",
utype = "volume",
scale = 0.00056826125,
default = "l",
},
["impqt"] = {
name1 = "imperial quart",
symbol = "imp qt",
utype = "volume",
scale = 0.0011365225,
default = "ml USoz",
customary= 3,
},
["kilderkin"] = {
symbol = "kilderkin",
usename = 1,
utype = "volume",
scale = 0.08182962,
default = "l impgal USgal",
},
["koilbbl"] = {
name1 = "thousand barrels",
name2 = "thousand barrels",
symbol = "kbbl",
utype = "volume",
scale = 158.987294928,
default = "v * 1.58987294928 < 10 ! ! e3 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["L"] = {
_name1 = "litre",
_name1_us= "liter",
_symbol = "L",
utype = "volume",
scale = 0.001,
prefixes = 1,
default = "impgal USgal",
link = "Litre",
},
["l"] = {
_name1 = "litre",
_name1_us= "liter",
_symbol = "l",
utype = "volume",
scale = 0.001,
prefixes = 1,
default = "impgal USgal",
link = "Litre",
},
["m3"] = {
_name1 = "cubic metre",
_name1_us= "cubic meter",
_symbol = "m<sup>3</sup>",
prefix_position= 7,
utype = "volume",
scale = 1,
prefixes = 3,
default = "cuft",
link = "Cubic metre",
},
["Mbbl"] = {
name1 = "thousand barrels",
name2 = "thousand barrels",
symbol = "Mbbl",
utype = "volume",
scale = 158.987294928,
default = "v * 1.58987294928 < 10 ! e3 ! ! m3",
link = "Barrel (unit)#Oil barrel",
},
["MMoilbbl"] = {
name1 = "million barrels",
name2 = "million barrels",
symbol = "MMbbl",
utype = "volume",
scale = 158987.294928,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["Moilbbl"] = {
name1 = "million barrels",
name2 = "million barrels",
symbol = "Mbbl",
utype = "volume",
scale = 158987.294928,
default = "v * 1.58987294928 < 10 ! e3 ! e6 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["MTON"] = {
name1 = "measurement ton",
symbol = "MTON",
utype = "volume",
scale = 1.13267386368,
default = "m3",
},
["MUSgal"] = {
name1 = "million US gallons",
name1_us = "million U.S. gallons",
name2 = "million US gallons",
name2_us = "million U.S. gallons",
symbol = "million US gal",
sym_us = "million U.S. gal",
utype = "volume",
scale = 3785.411784,
default = "Ml",
link = "US gallon",
},
["oilbbl"] = {
name1 = "barrel",
symbol = "bbl",
utype = "volume",
scale = 0.158987294928,
default = "m3",
link = "Barrel (unit)#Oil barrel",
},
["stere"] = {
symbol = "stere",
usename = 1,
utype = "volume",
scale = 1,
default = "cuft",
},
["Toilbbl"] = {
name1 = "trillion barrels",
name2 = "trillion barrels",
symbol = "Tbbl",
utype = "volume",
scale = 158987294928,
default = "v * 1.58987294928 < 10 ! e9 ! e12 ! m3",
link = "Barrel (unit)#Oil barrel",
},
["USbbl"] = {
name1 = "US barrel",
name1_us = "U.S. barrel",
symbol = "US bbl",
sym_us = "U.S. bbl",
utype = "volume",
scale = 0.119240471196,
default = "l USgal impgal",
link = "Barrel (unit)",
},
["USbeerbbl"] = {
name1 = "US beer barrel",
name1_us = "U.S. beer barrel",
symbol = "US bbl",
sym_us = "U.S. bbl",
utype = "volume",
scale = 0.117347765304,
default = "l USgal impgal",
link = "Barrel (unit)",
},
["USbsh"] = {
name1 = "US bushel",
name1_us = "U.S. bushel",
symbol = "US bsh",
sym_us = "U.S. bsh",
utype = "volume",
scale = 0.03523907016688,
default = "l USdrygal impgal",
link = "Bushel",
},
["USbu"] = {
name1 = "US bushel",
name1_us = "U.S. bushel",
symbol = "US bu",
sym_us = "U.S. bu",
utype = "volume",
scale = 0.03523907016688,
default = "l USdrygal impgal",
link = "Bushel",
},
["USdrybbl"] = {
name1 = "US dry barrel",
name1_us = "U.S. dry barrel",
symbol = "US dry bbl",
sym_us = "U.S. dry bbl",
utype = "volume",
scale = 0.11562819898508,
default = "m3",
link = "Barrel (unit)",
},
["USdrygal"] = {
name1 = "US dry gallon",
name1_us = "U.S. dry gallon",
symbol = "US dry gal",
sym_us = "U.S. dry gal",
utype = "volume",
scale = 0.00440488377086,
default = "l",
link = "Gallon",
},
["USdrypt"] = {
name1 = "US dry pint",
name1_us = "U.S. dry pint",
symbol = "US dry pt",
sym_us = "U.S. dry pt",
utype = "volume",
scale = 0.0005506104713575,
default = "ml",
link = "Pint",
},
["USdryqt"] = {
name1 = "US dry quart",
name1_us = "U.S. dry quart",
symbol = "US dry qt",
sym_us = "U.S. dry qt",
utype = "volume",
scale = 0.001101220942715,
default = "ml",
link = "Quart",
},
["USflgal"] = {
name1 = "US gallon",
name1_us = "U.S. gallon",
symbol = "US fl gal",
sym_us = "U.S. fl gal",
utype = "volume",
scale = 0.003785411784,
default = "l impgal",
link = "Gallon",
},
["USgal"] = {
name1 = "US gallon",
name1_us = "U.S. gallon",
symbol = "US gal",
sym_us = "U.S. gal",
utype = "volume",
scale = 0.003785411784,
default = "l impgal",
},
["USgi"] = {
name1 = "gill",
symbol = "gi",
utype = "volume",
scale = 0.0001182941183,
default = "ml impoz",
link = "Gill (unit)",
},
["USkenning"] = {
name1 = "US kenning",
name1_us = "U.S. kenning",
symbol = "US kenning",
sym_us = "U.S. kenning",
utype = "volume",
scale = 0.01761953508344,
default = "l impgal",
link = "Kenning (unit)",
},
["USmin"] = {
name1 = "US minim",
name1_us = "U.S. minim",
symbol = "US min",
sym_us = "U.S. min",
utype = "volume",
scale = 0.000000061611519921875,
default = "ml",
link = "Minim (unit)",
},
["USoz"] = {
name1 = "US fluid ounce",
name1_us = "U.S. fluid ounce",
symbol = "US fl oz",
sym_us = "U.S. fl oz",
utype = "volume",
scale = 0.0000295735295625,
default = "ml",
},
["USpk"] = {
name1 = "US peck",
name1_us = "U.S. peck",
symbol = "US pk",
sym_us = "U.S. pk",
utype = "volume",
scale = 0.00880976754172,
default = "l impgal",
link = "Peck",
},
["USpt"] = {
name1 = "US pint",
name1_us = "U.S. pint",
symbol = "US pt",
sym_us = "U.S. pt",
utype = "volume",
scale = 0.000473176473,
default = "l imppt",
link = "Pint",
},
["USqt"] = {
name1 = "US quart",
name1_us = "U.S. quart",
symbol = "US qt",
sym_us = "U.S. qt",
utype = "volume",
scale = 0.000946352946,
default = "ml",
link = "Quart",
customary= 1,
},
["USquart"] = {
name1 = "US quart",
name1_us = "U.S. quart",
symbol = "US qt",
sym_us = "U.S. qt",
utype = "volume",
scale = 0.000946352946,
default = "ml impoz",
link = "Quart",
},
["UStbsp"] = {
name1 = "US tablespoon",
name1_us = "U.S. tablespoon",
symbol = "US tbsp",
sym_us = "U.S. tbsp",
utype = "volume",
scale = 1.4786764781250001e-5,
default = "ml",
},
["winecase"] = {
symbol = "case",
usename = 1,
utype = "volume",
scale = 0.009,
default = "l",
link = "Case (goods)",
},
["*U.S.drygal"] = {
target = "USdrygal",
sp_us = true,
customary= 2,
},
["*U.S.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
customary= 2,
},
["+USdrygal"] = {
target = "USdrygal",
customary= 1,
},
["+usfloz"] = {
target = "USoz",
link = "Fluid ounce",
customary= 1,
},
["+USgal"] = {
target = "USgal",
customary= 1,
},
["+USoz"] = {
target = "USoz",
customary= 1,
},
["@impgal"] = {
target = "impgal",
link = "Gallon",
customary= 3,
},
["acre feet"] = {
target = "acre-ft",
},
["acre foot"] = {
target = "acre-foot",
},
["acre ft"] = {
target = "acre-ft",
},
["acre-feet"] = {
target = "acre-ft",
},
["acre.foot"] = {
target = "acre-foot",
},
["acre.ft"] = {
target = "acre-ft",
},
["acre·ft"] = {
target = "acre-ft",
},
["bushels"] = {
target = "USbsh",
},
["cid"] = {
target = "CID",
},
["ft3"] = {
target = "cuft",
},
["gal"] = {
target = "USgal",
},
["gallon"] = {
shouldbe = "Use %{USgal%} for US gallons or %{impgal%} for imperial gallons (not %{gallon%})",
},
["gallons"] = {
shouldbe = "Use %{USgal%} for US gallons or %{impgal%} for imperial gallons (not %{gallons%})",
},
["Gcuft"] = {
target = "e9cuft",
},
["impfloz"] = {
target = "impoz",
},
["Impgal"] = {
target = "impgal",
},
["in3"] = {
target = "cuin",
symbol = "in<sup>3</sup>",
},
["kcuft"] = {
target = "e3cuft",
},
["kcum"] = {
target = "e3m3",
},
["km³"] = {
target = "km3",
},
["liter"] = {
target = "L",
sp_us = true,
},
["liters"] = {
target = "L",
sp_us = true,
},
["litre"] = {
target = "L",
},
["litres"] = {
target = "L",
},
["Mcuft"] = {
target = "e6cuft",
},
["Mcum"] = {
target = "e6m3",
},
["Mft3"] = {
target = "e6cuft",
},
["mi3"] = {
target = "cumi",
},
["m³"] = {
target = "m3",
},
["Pcuft"] = {
target = "e15cuft",
},
["pt"] = {
shouldbe = "Use %{USpt%} for US pints or %{imppt%} for imperial pints (not %{pt%})",
},
["qt"] = {
shouldbe = "Use %{USqt%} for US quarts or %{impqt%} for imperial quarts (not %{qt%})",
},
["Tcuft"] = {
target = "e12cuft",
},
["Tft3"] = {
target = "e12cuft",
},
["U.S.bbl"] = {
target = "USbbl",
sp_us = true,
default = "l U.S.gal impgal",
},
["U.S.beerbbl"] = {
target = "USbeerbbl",
sp_us = true,
default = "l U.S.gal impgal",
},
["U.S.bsh"] = {
target = "USbsh",
sp_us = true,
default = "l U.S.drygal impgal",
},
["U.S.bu"] = {
target = "USbu",
sp_us = true,
default = "l U.S.drygal impgal",
},
["U.S.drybbl"] = {
target = "USdrybbl",
sp_us = true,
},
["U.S.drygal"] = {
target = "USdrygal",
sp_us = true,
},
["U.S.drypt"] = {
target = "USdrypt",
sp_us = true,
},
["U.S.dryqt"] = {
target = "USdryqt",
sp_us = true,
},
["U.S.flgal"] = {
target = "USflgal",
sp_us = true,
},
["U.S.floz"] = {
target = "USoz",
sp_us = true,
},
["U.S.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
link = "U.S. gallon",
},
["u.s.gal"] = {
target = "USgal",
sp_us = true,
default = "L impgal",
link = "U.S. gallon",
},
["U.S.gi"] = {
target = "USgi",
sp_us = true,
},
["U.S.kenning"] = {
target = "USkenning",
sp_us = true,
},
["U.S.oz"] = {
target = "USoz",
sp_us = true,
},
["U.S.pk"] = {
target = "USpk",
sp_us = true,
},
["U.S.pt"] = {
target = "USpt",
sp_us = true,
},
["U.S.qt"] = {
target = "USqt",
sp_us = true,
default = "L impqt",
customary= 2,
},
["usbbl"] = {
target = "USbbl",
},
["usbeerbbl"] = {
target = "USbeerbbl",
},
["usbsh"] = {
target = "USbsh",
},
["usbu"] = {
target = "USbu",
},
["usdrybbl"] = {
target = "USdrybbl",
},
["usdrygal"] = {
target = "USdrygal",
},
["usdrypt"] = {
target = "USdrypt",
},
["usdryqt"] = {
target = "USdryqt",
},
["USfloz"] = {
target = "USoz",
},
["usfloz"] = {
target = "USoz",
},
["USGAL"] = {
target = "USgal",
},
["usgal"] = {
target = "USgal",
},
["usgi"] = {
target = "USgi",
},
["uskenning"] = {
target = "USkenning",
},
["usoz"] = {
target = "USoz",
},
["uspk"] = {
target = "USpk",
},
["uspt"] = {
target = "USpt",
},
["usqt"] = {
target = "USqt",
},
["yd3"] = {
target = "cuyd",
},
["cuft/sqmi"] = {
per = { "cuft", "sqmi" },
utype = "volume per unit area",
default = "m3/km2",
},
["m3/ha"] = {
name1 = "cubic metre per hectare",
name1_us = "cubic meter per hectare",
name2 = "cubic metres per hectare",
name2_us = "cubic meters per hectare",
symbol = "m<sup>3</sup>/ha",
utype = "volume per unit area",
scale = 0.0001,
default = "USbu/acre",
link = "Hectare",
},
["m3/km2"] = {
per = { "m3", "km2" },
utype = "volume per unit area",
default = "cuft/sqmi",
},
["U.S.gal/acre"] = {
per = { "U.S.gal", "acre" },
utype = "volume per unit area",
default = "m3/km2",
},
["USbu/acre"] = {
name2 = "US bushels per acre",
symbol = "US bushel per acre",
usename = 1,
utype = "volume per unit area",
scale = 8.7077638761350888e-6,
default = "m3/ha",
link = "Bushel",
},
["USgal/acre"] = {
per = { "USgal", "acre" },
utype = "volume per unit area",
default = "m3/km2",
},
["cuyd/mi"] = {
per = { "cuyd", "mi" },
utype = "volume per unit length",
default = "m3/km",
},
["m3/km"] = {
per = { "m3", "km" },
utype = "volume per unit length",
default = "cuyd/mi",
},
["mich"] = {
combination= { "ch", "mi" },
multiple = { 80 },
utype = "length",
},
["michlk"] = {
combination= { "chlk", "mi" },
multiple = { 80 },
utype = "length",
},
["michainlk"] = {
combination= { "chainlk", "mi" },
multiple = { 80 },
utype = "length",
},
["miyd"] = {
combination= { "yd", "mi" },
multiple = { 1760 },
utype = "length",
},
["miydftin"] = {
combination= { "in", "ft", "yd", "mi" },
multiple = { 12, 3, 1760 },
utype = "length",
},
["mift"] = {
combination= { "ft", "mi" },
multiple = { 5280 },
utype = "length",
},
["ydftin"] = {
combination= { "in", "ft", "yd" },
multiple = { 12, 3 },
utype = "length",
},
["ydft"] = {
combination= { "ft", "yd" },
multiple = { 3 },
utype = "length",
},
["ftin"] = {
combination= { "in", "ft" },
multiple = { 12 },
utype = "length",
},
["footin"] = {
combination= { "in", "foot" },
multiple = { 12 },
utype = "length",
},
["handin"] = {
combination= { "in", "hand" },
multiple = { 4 },
utype = "length",
},
["lboz"] = {
combination= { "oz", "lb" },
multiple = { 16 },
utype = "mass",
},
["stlb"] = {
combination= { "lb", "st" },
multiple = { 14 },
utype = "mass",
},
["stlboz"] = {
combination= { "oz", "lb", "st" },
multiple = { 16, 14 },
utype = "mass",
},
["st and lb"] = {
combination= { "lb", "st" },
multiple = { 14 },
utype = "mass",
},
["GN LTf"] = {
combination= { "GN", "-LTf" },
utype = "force",
},
["GN LTf STf"] = {
combination= { "GN", "-LTf", "-STf" },
utype = "force",
},
["GN STf"] = {
combination= { "GN", "-STf" },
utype = "force",
},
["GN STf LTf"] = {
combination= { "GN", "-STf", "-LTf" },
utype = "force",
},
["kN LTf"] = {
combination= { "kN", "-LTf" },
utype = "force",
},
["kN LTf STf"] = {
combination= { "kN", "-LTf", "-STf" },
utype = "force",
},
["kN STf"] = {
combination= { "kN", "-STf" },
utype = "force",
},
["kN STf LTf"] = {
combination= { "kN", "-STf", "-LTf" },
utype = "force",
},
["LTf STf"] = {
combination= { "-LTf", "-STf" },
utype = "force",
},
["MN LTf"] = {
combination= { "MN", "-LTf" },
utype = "force",
},
["MN LTf STf"] = {
combination= { "MN", "-LTf", "-STf" },
utype = "force",
},
["MN STf"] = {
combination= { "MN", "-STf" },
utype = "force",
},
["MN STf LTf"] = {
combination= { "MN", "-STf", "-LTf" },
utype = "force",
},
["STf LTf"] = {
combination= { "-STf", "-LTf" },
utype = "force",
},
["L/100 km mpgimp"] = {
combination= { "L/100 km", "mpgimp" },
utype = "fuel efficiency",
},
["l/100 km mpgimp"] = {
combination= { "l/100 km", "mpgimp" },
utype = "fuel efficiency",
},
["L/100 km mpgUS"] = {
combination= { "L/100 km", "mpgus" },
utype = "fuel efficiency",
},
["L/100 km mpgus"] = {
combination= { "L/100 km", "mpgus" },
utype = "fuel efficiency",
},
["l/100 km mpgus"] = {
combination= { "l/100 km", "mpgus" },
utype = "fuel efficiency",
},
["mpgimp L/100 km"] = {
combination= { "mpgimp", "L/100 km" },
utype = "fuel efficiency",
},
["LT ST t"] = {
combination= { "lt", "-ST", "t" },
utype = "mass",
},
["LT t ST"] = {
combination= { "lt", "t", "-ST" },
utype = "mass",
},
["ST LT t"] = {
combination= { "-ST", "lt", "t" },
utype = "mass",
},
["ST t LT"] = {
combination= { "-ST", "t", "lt" },
utype = "mass",
},
["t LT ST"] = {
combination= { "t", "lt", "-ST" },
utype = "mass",
},
["ton"] = {
combination= { "LT", "ST" },
utype = "mass",
},
["kPa kg/cm2"] = {
combination= { "kPa", "kgf/cm2" },
utype = "pressure",
},
["kPa lb/in2"] = {
combination= { "kPa", "-lb/in2" },
utype = "pressure",
},
["floz"] = {
combination= { "impoz", "USoz" },
utype = "volume",
},
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local default_exceptions = {
-- Prefixed units with a default different from that of the base unit.
-- Each key item is a prefixed symbol (unitcode for engineering notation).
["cm<sup>2</sup>"] = "sqin",
["dm<sup>2</sup>"] = "sqin",
["e3acre"] = "km2",
["e3m2"] = "e6sqft",
["e6acre"] = "km2",
["e6ha"] = "e6acre",
["e6km2"] = "e6sqmi",
["e6m2"] = "e6sqft",
["e6sqft"] = "v * 9.290304 < 100 ! e3 ! e6 ! m2",
["e6sqmi"] = "e6km2",
["hm<sup>2</sup>"] = "acre",
["km<sup>2</sup>"] = "sqmi",
["mm<sup>2</sup>"] = "sqin",
["aJ"] = "eV",
["e3BTU"] = "MJ",
["e6BTU"] = "GJ",
["EJ"] = "kWh",
["fJ"] = "keV",
["GJ"] = "kWh",
["MJ"] = "kWh",
["PJ"] = "kWh",
["pJ"] = "MeV",
["TJ"] = "kWh",
["YJ"] = "kWh",
["yJ"] = "μeV",
["ZJ"] = "kWh",
["zJ"] = "meV",
["e12cuft/a"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3/a",
["e12cuft/d"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3/d",
["e12m3/a"] = "Tcuft/a",
["e12m3/d"] = "Tcuft/d",
["e3cuft/a"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/a",
["e3cuft/d"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/d",
["e3cuft/s"] = "v * 2.8316846592 < 100 ! ! e3 ! m3/s",
["e3m3/a"] = "v < 28.316846592 ! k ! M ! cuft/a",
["e3m3/d"] = "v < 28.316846592 ! k ! M ! cuft/d",
["e3m3/s"] = "v < 28.316846592 ! k ! M ! cuft/s",
["e3USgal/a"] = "v * 3.785411784 < 1000 ! ! e3 ! m3/a",
["e6cuft/a"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/a",
["e6cuft/d"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/d",
["e6cuft/s"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3/s",
["e6m3/a"] = "v < 28.316846592 ! M ! G ! cuft/a",
["e6m3/d"] = "v < 28.316846592 ! M ! G ! cuft/d",
["e6m3/s"] = "v < 28.316846592 ! e6 ! e9 ! cuft/s",
["e6USgal/a"] = "v * 3.785411784 < 1000 ! e3 ! e6 ! m3/a",
["e9cuft/a"] = "m3/a",
["e9cuft/d"] = "v * 2.8316846592 < 100 ! e6 ! e9 ! m3/d",
["e9m3/a"] = "v < 28.316846592 ! G ! T ! cuft/a",
["e9m3/d"] = "v < 28.316846592 ! G ! T ! cuft/d",
["e9m3/s"] = "v < 28.316846592 ! e9 ! e12 ! cuft/s",
["e9USgal/a"] = "v * 3.785411784 < 1000 ! e6 ! e9 ! m3/a",
["e9USgal/s"] = "v * 3.785411784 < 1000 ! e6 ! e9 ! m3/s",
["nN"] = "gr-f",
["μN"] = "gr-f",
["mN"] = "oz-f",
["am"] = "in",
["cm"] = "in",
["dam"] = "ft",
["dm"] = "in",
["e12km"] = "e12mi",
["e12mi"] = "e12km",
["e3AU"] = "ly",
["e3km"] = "e3mi",
["e3mi"] = "e3km",
["e6km"] = "e6mi",
["e6mi"] = "e6km",
["e9km"] = "AU",
["e9mi"] = "e9km",
["Em"] = "mi",
["fm"] = "in",
["Gm"] = "mi",
["hm"] = "ft",
["km"] = "mi",
["mm"] = "in",
["Mm"] = "mi",
["nm"] = "in",
["Pm"] = "mi",
["pm"] = "in",
["Tm"] = "mi",
["Ym"] = "mi",
["ym"] = "in",
["Zm"] = "mi",
["zm"] = "in",
["μm"] = "in",
["e12lb"] = "v * 4.5359237 < 10 ! Mt ! Gt",
["e3lb"] = "v * 4.5359237 < 10 ! kg ! t",
["e3ozt"] = "v * 0.311034768 < 10 ! kg ! t",
["e3t"] = "LT ST",
["e6carat"] = "t",
["e6lb"] = "v * 4.5359237 < 10 ! t ! kilotonne",
["e6ozt"] = "lb kg",
["e6ST"] = "Mt",
["e6t"] = "LT ST",
["e9lb"] = "v * 4.5359237 < 10 ! kilotonne ! Mt",
["e9t"] = "LT ST",
["Gg"] = "lb",
["kg"] = "lb",
["mg"] = "gr",
["Mg"] = "LT ST",
["ng"] = "gr",
["μg"] = "gr",
["mBq"] = "fCi",
["kBq"] = "nCi",
["MBq"] = "μCi",
["GBq"] = "mCi",
["TBq"] = "Ci",
["PBq"] = "kCi",
["EBq"] = "kCi",
["fCi"] = "mBq",
["pCi"] = "Bq",
["nCi"] = "Bq",
["μCi"] = "kBq",
["mCi"] = "MBq",
["kCi"] = "TBq",
["MCi"] = "PBq",
["ns"] = "μs",
["μs"] = "ms",
["ms"] = "s",
["ks"] = "h",
["Ms"] = "week",
["Gs"] = "decade",
["Ts"] = "millennium",
["Ps"] = "million year",
["Es"] = "thousand million year",
["MK"] = "keVT",
["cL"] = "impoz usoz",
["cl"] = "impoz usoz",
["cm<sup>3</sup>"] = "cuin",
["dL"] = "impoz usoz",
["dl"] = "impoz usoz",
["mm<sup>3</sup>"] = "cuin",
["dm<sup>3</sup>"] = "cuin",
["e12cuft"] = "v * 2.8316846592 < 100 ! e9 ! e12 ! m3",
["e12impgal"] = "v * 4.54609 < 1000 ! T ! P ! l",
["e12m3"] = "v < 28.316846592 ! T ! P ! cuft",
["e12U.S.gal"] = "v * 3.785411784 < 1000 ! T ! P ! l",
["e12USgal"] = "v * 3.785411784 < 1000 ! T ! P ! l",
["e15cuft"] = "v * 2.8316846592 < 100 ! e12 ! e15 ! m3",
["e15m3"] = "Pcuft",
["e3bdft"] = "v * 0.23597372167 < 100 ! e3 ! e6 ! m3",
["e3cuft"] = "v * 2.8316846592 < 100 ! ! e3 ! m3",
["e3impgal"] = "v * 4.54609 < 1000 ! k ! M ! l",
["e3m3"] = "v < 28.316846592 ! k ! M ! cuft",
["e3U.S.gal"] = "v * 3.785411784 < 1000 ! k ! M ! l",
["e3USgal"] = "v * 3.785411784 < 1000 ! k ! M ! l",
["e6bdft"] = "v * 0.23597372167 < 100 ! e3 ! e6 ! m3",
["e6cuft"] = "v * 2.8316846592 < 100 ! e3 ! e6 ! m3",
["e6cuyd"] = "v * 7.64554857984 < 10 ! e3 ! e6 ! m3",
["e6impgal"] = "v * 4.54609 < 1000 ! M ! G ! l",
["e6L"] = "USgal",
["e6m3"] = "v < 28.316846592 ! M ! G ! cuft",
["e6U.S.gal"] = "v * 3.785411784 < 1000 ! M ! G ! l",
["e6USgal"] = "v * 3.785411784 < 1000 ! M ! G ! l",
["e9bdft"] = "v * 0.23597372167 < 100 ! e6 ! e9 ! m3",
["e9cuft"] = "v * 2.8316846592 < 100 ! e6 ! e9 ! m3",
["e9impgal"] = "v * 4.54609 < 1000 ! G ! T ! l",
["e9m3"] = "v < 28.316846592 ! G ! T ! cuft",
["e9U.S.gal"] = "v * 3.785411784 < 1000 ! G ! T ! l",
["e9USgal"] = "v * 3.785411784 < 1000 ! G ! T ! l",
["GL"] = "cuft",
["Gl"] = "cuft",
["kL"] = "cuft",
["kl"] = "cuft",
["km<sup>3</sup>"] = "cumi",
["mL"] = "impoz usoz",
["ml"] = "impoz usoz",
["Ml"] = "v < 28.316846592 ! e3 ! e6 ! cuft",
["ML"] = "v < 28.316846592 ! e3 ! e6 ! cuft",
["TL"] = "cumi",
["Tl"] = "cumi",
["μL"] = "cuin",
["μl"] = "cuin",
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local link_exceptions = {
-- Prefixed units with a linked article different from that of the base unit.
-- Each key item is a prefixed symbol (not unitcode).
["mm<sup>2</sup>"] = "Square millimetre",
["cm<sup>2</sup>"] = "Square centimetre",
["dm<sup>2</sup>"] = "Square decimetre",
["km<sup>2</sup>"] = "Square kilometre",
["kJ"] = "Kilojoule",
["MJ"] = "Megajoule",
["GJ"] = "Gigajoule",
["TJ"] = "Terajoule",
["fm"] = "Femtometre",
["pm"] = "Picometre",
["nm"] = "Nanometre",
["μm"] = "Micrometre",
["mm"] = "Millimetre",
["cm"] = "Centimetre",
["dm"] = "Decimetre",
["dam"] = "Decametre",
["hm"] = "Hectometre",
["km"] = "Kilometre",
["Mm"] = "Megametre",
["Gm"] = "Gigametre",
["Tm"] = "Terametre",
["Pm"] = "Petametre",
["Em"] = "Exametre",
["Zm"] = "Zettametre",
["Ym"] = "Yottametre",
["μg"] = "Microgram",
["mg"] = "Milligram",
["kg"] = "Kilogram",
["Mg"] = "Tonne",
["yW"] = "Yoctowatt",
["zW"] = "Zeptowatt",
["aW"] = "Attowatt",
["fW"] = "Femtowatt",
["pW"] = "Picowatt",
["nW"] = "Nanowatt",
["μW"] = "Microwatt",
["mW"] = "Milliwatt",
["kW"] = "Kilowatt",
["MW"] = "Megawatt",
["GW"] = "Gigawatt",
["TW"] = "Terawatt",
["PW"] = "Petawatt",
["EW"] = "Exawatt",
["ZW"] = "Zettawatt",
["YW"] = "Yottawatt",
["as"] = "Attosecond",
["fs"] = "Femtosecond",
["ps"] = "Picosecond",
["ns"] = "Nanosecond",
["μs"] = "Microsecond",
["ms"] = "Millisecond",
["ks"] = "Kilosecond",
["Ms"] = "Megasecond",
["Gs"] = "Gigasecond",
["Ts"] = "Terasecond",
["Ps"] = "Petasecond",
["Es"] = "Exasecond",
["Zs"] = "Zettasecond",
["Ys"] = "Yottasecond",
["mm<sup>3</sup>"] = "Cubic millimetre",
["cm<sup>3</sup>"] = "Cubic centimetre",
["dm<sup>3</sup>"] = "Cubic decimetre",
["dam<sup>3</sup>"] = "Cubic decametre",
["km<sup>3</sup>"] = "Cubic kilometre",
["μL"] = "Microlitre",
["μl"] = "Microlitre",
["mL"] = "Millilitre",
["ml"] = "Millilitre",
["cL"] = "Centilitre",
["cl"] = "Centilitre",
["dL"] = "Decilitre",
["dl"] = "Decilitre",
["daL"] = "Decalitre",
["dal"] = "Decalitre",
["hL"] = "Hectolitre",
["hl"] = "Hectolitre",
["kL"] = "Kilolitre",
["kl"] = "Kilolitre",
["ML"] = "Megalitre",
["Ml"] = "Megalitre",
["GL"] = "Gigalitre",
["Gl"] = "Gigalitre",
["TL"] = "Teralitre",
["Tl"] = "Teralitre",
["PL"] = "Petalitre",
["Pl"] = "Petalitre",
}
---------------------------------------------------------------------------
-- Do not change the data in this table because it is created by running --
-- a script that reads the wikitext from a wiki page (see note above). --
---------------------------------------------------------------------------
local per_unit_fixups = {
-- Automatically created per units of form "x/y" may have their unit type
-- changed, for example, "length/time" is changed to "speed".
-- Other adjustments can also be specified.
["/area"] = "per unit area",
["/volume"] = "per unit volume",
["area/area"] = "area per unit area",
["energy/length"] = "energy per unit length",
["energy/mass"] = "energy per unit mass",
["energy/time"] = { utype = "power", link = "Power (physics)" },
["energy/volume"] = "energy per unit volume",
["force/area"] = { utype = "pressure", link = "Pressure" },
["length/length"] = { utype = "gradient", link = "Grade (slope)" },
["length/time"] = { utype = "speed", link = "Speed" },
["length/time/time"] = { utype = "acceleration", link = "Acceleration" },
["mass/area"] = { utype = "pressure", multiplier = 9.80665 },
["mass/length"] = "linear density",
["mass/mass"] = "concentration",
["mass/power"] = "mass per unit power",
["mass/time"] = "mass per unit time",
["mass/volume"] = { utype = "density", link = "Density" },
["power/mass"] = "power per unit mass",
["power/volume"] = { link = "Power density" },
["pressure/length"] = "fracture gradient",
["speed/time"] = { utype = "acceleration", link = "Acceleration" },
["volume/area"] = "volume per unit area",
["volume/length"] = "volume per unit length",
["volume/time"] = "flow",
}
return {
all_units = all_units,
default_exceptions = default_exceptions,
link_exceptions = link_exceptions,
per_unit_fixups = per_unit_fixups,
}
df9e48c56b5ed9957eaef10e36df353b161075f5
Module:Convert/text
828
48
112
111
2022-09-04T15:24:32Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- Text used by Module:Convert for enwiki.
-- This is a separate module to simplify translation for use on another wiki.
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki.
-- Some units accept an SI prefix before the unit code, such as "kg" for kilogram.
local SIprefixes = {
-- The prefix field is what the prefix should be, if different from the prefix used.
['Y'] = { exponent = 24, name = 'yotta', },
['Z'] = { exponent = 21, name = 'zetta', },
['E'] = { exponent = 18, name = 'exa' , },
['P'] = { exponent = 15, name = 'peta' , },
['T'] = { exponent = 12, name = 'tera' , },
['G'] = { exponent = 9, name = 'giga' , },
['M'] = { exponent = 6, name = 'mega' , },
['k'] = { exponent = 3, name = 'kilo' , },
['h'] = { exponent = 2, name = 'hecto', },
['da']= { exponent = 1, name = 'deca' , name_us = 'deka' },
['d'] = { exponent = -1, name = 'deci' , },
['c'] = { exponent = -2, name = 'centi', },
['m'] = { exponent = -3, name = 'milli', },
['μ'] = { exponent = -6, name = 'micro', }, -- key = 'GREEK SMALL LETTER MU' (U+03BC) utf-8 CE BC
['µ'] = { exponent = -6, name = 'micro', prefix = 'μ' }, -- key = 'MICRO SIGN' (U+00B5) utf-8 C2 B5
['u'] = { exponent = -6, name = 'micro', prefix = 'μ' }, -- not an SI prefix, but allow for people typing this
['n'] = { exponent = -9, name = 'nano' , },
['p'] = { exponent =-12, name = 'pico' , },
['f'] = { exponent =-15, name = 'femto', },
['a'] = { exponent =-18, name = 'atto' , },
['z'] = { exponent =-21, name = 'zepto', },
['y'] = { exponent =-24, name = 'yocto', },
}
-- Some units can be qualified with one of the following prefixes, when linked.
local customary_units = {
{ "US", link = "United States customary units" },
{ "U.S.", link = "United States customary units" },
{ "imperial", link = "Imperial units" },
{ "imp", link = "Imperial units" },
}
-- Names when using engineering notation (a prefix of "eN" where N is a number; example "e6km").
-- key = { "name", link = "article title", exponent = numeric_key_value }
-- If lk=on and link is defined, the name of the number will appear as a link.
local eng_scales = {
["3"] = { "thousand", exponent = 3 },
["6"] = { "million", exponent = 6 },
["9"] = { "billion", link = "1000000000 (number)", exponent = 9 },
["12"] = { "trillion", link = "1000000000000 (number)", exponent = 12 },
["15"] = { "quadrillion", link = "1000000000000000 (number)", exponent = 15 },
}
local all_categories = {
unit = "[[Category:Convert errors]]",
option = "[[Category:Convert errors]]",
warning = '[[Category:Convert invalid options]]',
tracking = '[[Category:Convert tracking]]',
}
-- For some error messages, the following puts the wanted style around
-- each unit code marked like '...%{ft%}...'.
local unitcode_regex = '%%([{}])'
local unitcode_replace = { ['{'] = '"', ['}'] = '"' } -- no longer need the more elaborate substitute used before 2013-09-28
-- All messages that may be displayed if a problem occurs.
local all_messages = {
-- Message format string: $1=title, $2=text, $3=category, $4=anchor.
-- Each displayed message starts with "Convert:" so can easily locate by searching article.
cvt_format = '<sup class="noprint Inline-Template" style="white-space:nowrap;">[<i>[[Help:Convert messages#$4|<span title="Convert: $1">convert: $2</span>]]</i>]</sup>$3<span class="error"></span>',
cvt_format2 = '<sup class="noprint Inline-Template" style="white-space:nowrap;">[[Help:Convert messages#$4|<span title="Convert: $1">$2</span>]]</sup>$3<span class="error"></span>',
cvt_format_preview = '<strong class="error">Error in convert: $1 [[Help:Convert messages#$4|(help)]]</strong>$3',
-- Each of following messages is a table:
-- { [1] = 'title', -- mouseover title text
-- [2] = 'text', -- link text displayed in article
-- [3] = 'category key', -- key to lookup category in all_categories
-- [4] = 'anchor', -- anchor for link to relevant section on help page
-- regex = gsub_regex,
-- replace = gsub_table,
-- } Mouseover title text Link text CatKey Anchor
cvt_bad_input = { 'input "$1" must be a number and unit' , 'invalid input' , 'option', 'invalid_input' },
cvt_bad_num = { 'Value "$1" must be a number' , 'invalid number' , 'option', 'invalid_number' },
cvt_big_prec = { 'Precision "$1" is too large' , 'precision too large' , 'option', 'precision_too_large' },
cvt_invalid_num = { 'Number has overflowed' , 'number overflow' , 'option', 'number_overflow' },
cvt_no_num = { 'Needs the number to be converted' , 'needs a number' , 'option', 'needs_number' },
cvt_no_num2 = { 'Needs another number for a range' , 'needs another number', 'option', 'needs_another_number' },
cvt_bad_altitude = { '"$1" needs an integer' , 'invalid altitude' , 'option', 'invalid_altitude' },
cvt_bad_frac = { '"$1" needs an integer above 1' , 'invalid fraction' , 'option', 'invalid_fraction' },
cvt_bad_prec = { 'Precision "$1" must be an integer' , 'invalid precision' , 'option', 'invalid_precision' },
cvt_bad_sigfig = { '"$1" needs a positive integer' , 'invalid sigfig' , 'option', 'invalid_sigfig' },
cvt_empty_option = { 'Ignored empty option "$1"' , 'empty option' , 'option', 'empty_option' },
cvt_deprecated = { 'Option "$1" is deprecated' , '*' , 'option', 'deprecated_option', format = 'cvt_format2', nowarn = true },
cvt_no_spell = { 'Spelling is not available' , 'bug, ask for help' , 'option', 'ask_for_help' },
cvt_unknown_option = { 'Ignored invalid option "$1"' , 'invalid option' , 'option', 'invalid_option' },
cvt_wd_fail = { 'Unable to access Wikidata' , 'wikidata problem' , 'option', 'wikidata_problem' },
cvt_bad_default = { 'Unit "$1" has an invalid default' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_bad_unit = { 'Unit "$1" is invalid here' , 'unit invalid here' , 'unit' , 'unit_invalid_here' },
cvt_no_default = { 'Unit "$1" has no default output unit' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_no_unit = { 'Needs name of unit' , 'needs unit name' , 'unit' , 'needs_unit_name' },
cvt_unknown = { 'Unit name "$1" is not known' , 'unknown unit' , 'unit' , 'unknown_unit' },
cvt_should_be = { '$1' , 'ambiguous unit' , 'unit' , 'ambiguous_unit', regex = unitcode_regex, replace = unitcode_replace },
cvt_mismatch = { 'Cannot convert "$1" to "$2"' , 'unit mismatch' , 'unit' , 'unit_mismatch' },
cvt_bug_convert = { 'Bug: Cannot convert between specified units', 'bug, ask for help' , 'unit' , 'ask_for_help' },
cvt_lookup = { 'Unit "$1" is incorrectly defined' , 'bug, ask for help' , 'unit' , 'ask_for_help' },
}
-- Text to join input value/unit with output value/unit.
local disp_joins = {
-- [1]=before output, [2]=after output, [3]=between outputs in a combination; default "; "
-- [wantname] gives default abbr=off
["or"] = { " or " , "" , " or ", wantname = true },
["sqbr-sp"] = { " [" , "]" },
["sqbr-nbsp"] = { " [" , "]" },
["comma"] = { ", " , "" , ", " },
["slash-sp"] = { " / " , "" , wantname = true },
["slash-nbsp"] = { " / ", "" , wantname = true },
["slash-nosp"] = { "/" , "" , wantname = true },
["b"] = { " (" , ")" },
["(or)"] = { " (" , ")", " or " },
["br"] = { "<br />" , "" , wantname = true },
["br()"] = { "<br />(" , ")", wantname = true },
}
-- Text to separate values in a range.
local range_types = {
-- Specifying a table requires either:
-- * "off" and "on" values (for "abbr=off" and "abbr=on"), or
-- * "input" and "output" values (for LHS and RHS);
-- other fields are optional.
-- When "adj=on|abbr=off" applies, spaces in range text are replaced with hyphens.
-- With "exception = true", that also occurs with "adj=on|abbr=on".
-- If "adj" is defined here, that text (unchanged) is used with "adj=on".
["+"] = " + ",
[","] = ", ",
[", and"] = ", and ",
[", or"] = ", or ",
["by"] = " by ",
["-"] = "–",
["to about"] = " to about ",
["and"] = { off = " and ", on = " and ", exception = true },
["and(-)"] = { input = " and ", output = "–" },
["or"] = { off = " or " , on = " or " , exception = true },
["to"] = { off = " to " , on = " to " , exception = true },
["to(-)"] = { input = " to ", output = "–" },
["+/-"] = { off = " ± ", on = " ± ", adj = " ± ", is_range_change = true },
["by(x)"] = { input = " by ", output = " × ", out_range_x = true },
["x"] = { off = " by ", on = " × ", abbr_range_x = true },
["xx"] = " × ",
["*"] = "×",
["/"] = " / ", -- for a table of high/low temperatures with {{convert|83|/|63|F|disp=br()|abbr=values}}
}
local range_aliases = {
-- ["alternative name for a range"] = "standard range name"
["–"] = "-",
["–"] = "-",
["×"] = "x",
["×"] = "x",
["±"] = "+/-",
["±"] = "+/-",
}
-- Convert accepts range text delimited with whitespace, for example, {{convert|1 to 2|ft}}.
-- In addition, the following "words" are accepted without spaces, for example, {{convert|1-2|ft}}.
-- Words must be in correct order for searching, for example, 'x' after 'xx'.
local range_words = { '-', '–', 'xx', 'x', '*' }
local ranges = {
types = range_types,
aliases = range_aliases,
words = range_words,
}
-- Valid option names.
local en_option_name = {
-- ["local text for option name"] = "en name used in this module"
["$"] = "$",
["abbr"] = "abbr",
["adj"] = "adj",
["altitude_ft"] = "altitude_ft",
["altitude_m"] = "altitude_m",
["comma"] = "comma",
["debug"] = "debug",
["disp"] = "disp",
["frac"] = "frac",
["input"] = "input",
["lang"] = "lang",
["lk"] = "lk",
["order"] = "order",
["qid"] = "qid",
["qual"] = "qual",
["qualifier"] = "qual",
["round"] = "round",
["sigfig"] = "sigfig",
["sing"] = "adj", -- "sing" is an old alias for "adj"
["sortable"] = "sortable",
["sp"] = "sp",
["spell"] = "spell",
["stylein"] = "stylein",
["styleout"] = "styleout",
["tracking"] = "tracking",
}
-- Valid option values.
-- Convention: parms.opt_xxx refers to an option that is set here
-- (not intended to be set by the template which invokes this module).
-- Example: At enwiki, "abbr" includes:
-- ["values"] = "opt_values"
-- As a result, if the template uses abbr=values, Module:Convert sets:
-- parms["opt_values"] = true
-- parms["abbr"] = nil
-- Therefore parms.abbr will be nil, or will have one of the listed values
-- that do not start with "opt_".
-- An option value of form "xxx?" is the same as "xxx" but shows the input as deprecated.
local en_option_value = {
["$"] = 'TEXT', -- TEXT should be a currency symbol that will be used instead of "$"
["abbr"] = {
-- ["local text for option value"] = "en value used in this module"
["def"] = "", -- ignored (some wrapper templates call convert with "abbr=def" to mean "default abbreviation")
["h"] = "on", -- abbr=on + use "h" for hand unit (default)
["hh"] = "opt_hand_hh", -- abbr=on + use "hh" for hand unit
["in"] = "in", -- use symbol for LHS unit
["none"] = "off", -- old name for "off"
["off"] = "off", -- use name for all units
["on"] = "on", -- use symbol for all units
["out"] = "out", -- use symbol for RHS unit (default)
["unit"] = "unit", -- abbr=on but abbreviate units only: e6km → million km (not ×10⁶ km)
["values"] = "opt_values", -- show only input and output numbers, not units
["~"] = "opt_also_symbol", -- show input unit symbol as well as name
},
["adj"] = {
["mid"] = "opt_adjectival, opt_adj_mid", -- adj=on with user-specified text after input unit (between input and output)
["off"] = "", -- ignored (off is the default)
["on"] = "opt_adjectival", -- unit name is singular and hyphenated
["pre"] = "opt_one_preunit", -- user-specified text before input unit
["ri0"] = "opt_ri=0", -- round input with precision = 0
["ri1"] = "opt_ri=1", -- round input with precision = 1
["ri2"] = "opt_ri=2", -- round input with precision = 2
["ri3"] = "opt_ri=3", -- round input with precision = 3
},
["altitude_ft"] = 'INTEGER',
["altitude_m"] = 'INTEGER',
["comma"] = {
["5"] = "opt_comma5", -- only use numsep grouping if 5 or more digits
["gaps"] = "opt_gaps", -- use gaps, not numsep, to separate groups of digits
["gaps3"] = "opt_gaps, opt_gaps3", -- group only in threes rather than default of no gap before a single digit after decimal mark
["off"] = "opt_nocomma", -- no numsep in input or output numbers
},
["debug"] = {
["yes"] = "opt_sortable_debug", -- make the normally hidden sort key visible
},
["disp"] = {
["5"] = "opt_round=5?", -- round output value to nearest 5
["b"] = "b", -- join: '(...)'
["(or)"] = "(or)", -- join: '(...)' with 'or' between outputs in a combination
["br"] = "br", -- join: '<br />'
["br()"] = "br()", -- join: '<br />(...)'
["comma"] = "comma", -- join: ','
["flip"] = "opt_flip", -- reverse order of input/output
["number"] = "opt_output_number_only", -- display output value (not input, and not output symbol/name)
["or"] = "or", -- join: 'or'
["out"] = "opt_output_only",
["output number only"] = "opt_output_number_only",
["output only"] = "opt_output_only",
["preunit"] = "opt_two_preunits", -- user-specified text before input and output units
["sqbr"] = "sqbr", -- join: '[...]'
["table"] = "opt_table", -- output is suitable for a table cell with align="right"
["tablecen"] = "opt_tablecen", -- output is suitable for a table cell with align="center"
["unit"] = "opt_input_unit_only", -- display input symbol/name (not output, and not input value)
["unit or text"] = "opt_input_unit_only, opt_ignore_error", -- display input symbol/name, or given unit code if not known
["unit2"] = "opt_output_unit_only",
["x"] = "x", -- join: <first>...<second> (user-specified text)
},
["frac"] = 'INTEGER',
["input"] = 'TEXT', -- TEXT should be value><space><unitcode> or <wikidata-property-id>
["lang"] = { -- language for output digits (both en and local digits are always accepted for input)
["en"] = "opt_lang_en", -- use en digits for numbers, regardless of local language
["local"] = "opt_lang_local", -- use local digits for numbers (default, although config can change default to en)
},
["lk"] = {
["in"] = "in", -- link LHS unit name or symbol
["off"] = "off", -- do not link: same as default except for hand unit
["on"] = "on", -- link all unit names or symbols (but not twice for the same unit)
["out"] = "out", -- link RHS unit name or symbol
},
["order"] = {
["flip"] = "opt_flip", -- reverse order of input/output
["out"] = "opt_order_out", -- do not show input; instead, use order in output combination, with the first output shown as the input
},
["qid"] = 'TEXT', -- TEXT should be a Wikidata Q item identifier
["qual"] = 'TEXT', -- TEXT should be a Wikidata Q item identifier
["round"] = {
["0.5"] = "opt_round=0.5", -- round output value to nearest 0.5
["5"] = "opt_round=5", -- round output value to nearest 5
["10"] = "opt_round=10", -- round output value to nearest 10 (same as but clearer than "|-1")
["25"] = "opt_round=25", -- round output value to nearest 25
["50"] = "opt_round=50", -- round output value to nearest 50
["each"] = "opt_round_each", -- using default precision in a range, round each output separately (default uses highest precision of each item in range)
},
["sigfig"] = 'INTEGER',
["sortable"] = {
["off"] = "", -- ignored (off is the default)
["on"] = "opt_sortable_on", -- output sort key for use in a sortable table, based on value from converting to a standard base unit
["debug"] = "opt_sortable_on, opt_sortable_debug", -- |sortable=debug is the same as |sortable=on|debug=yes
},
["sp"] = {
["us"] = "opt_sp_us", -- use U.S. spelling (like "meter" instead of default "metre")
},
["spell"] = { -- only English spelling is supported; not scientific notation; only some fractions
["in"] = "opt_spell_in", -- spell input value in words
["In"] = "opt_spell_in, opt_spell_upper", -- spell input value in words with first letter uppercase
["on"] = "opt_spell_in, opt_spell_out", -- spell input and output values in words
["On"] = "opt_spell_in, opt_spell_out, opt_spell_upper", -- same, with first letter of first word in result uppercase
},
["stylein"] = 'TEXT',
["styleout"] = 'TEXT',
["tracking"] = 'TEXT',
}
local titles = {
["frac"] = "Fraction/styles.css",
["sfrac"] = "Sfrac/styles.css",
}
return {
SIprefixes = SIprefixes,
all_categories = all_categories,
all_messages = all_messages,
currency = { ['$'] = true, ['£'] = true, ['€'] = true, ['₱'] = true, ['₽'] = true, ['¥'] = true },
customary_units = customary_units,
disp_joins = disp_joins,
en_option_name = en_option_name,
en_option_value = en_option_value,
eng_scales = eng_scales,
ranges = ranges,
titles = titles,
}
05665ce7dee224b4474fd898266e157aab84691f
Template:Cite journal
10
49
114
113
2022-09-04T15:24:32Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:Citation/CS1|citation
|CitationClass=journal
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
50b33a0bde8c0dc83f3753f7873bcb448b565944
Module:Citation/CS1
828
50
116
115
2022-09-04T15:24:33Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require ('Module:No globals');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z ={}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- Boolean flag so that the category is added only once
local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local Frame; -- holds the module's frame table
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between
the first and last characters the name may use letters, digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
if not domain:match ('^[%w]') then -- first character must be letter or digit
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs ({'cash', 'company', 'today', 'org'}) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local err_msg = '';
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]);
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local cap = '';
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_code_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param>
utilities.set_message ('err_trans_missing_title', {chapter_source});
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = capture .. ' ' .. char_name;
else
err_msg = char_name .. ' ' .. 'character';
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded.
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local args, list, v = args, cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
tbl = rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap = '';
local cap2 = '';
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
trim = false;
end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials(first, position)
local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match(first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials, names = {}, {}; -- tables to hold name parts and initials
local i = 1; -- counter for number of initials
names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix
while names[i] do -- loop through the table
if 1 < i and names[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names[i] = names[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names[i]) then -- if a legitimate suffix
table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials, mw.ustring.sub(names[i], 1, 1)); -- insert the initial at end of initials table
end
i = i + 1; -- bump the counter
end
return table.concat(initials) -- Vancouver format does not include spaces.
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. ' ' .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add maint cat when name parameter value does not contain letters. Does not catch
mixed alphanumeric names so |last=A. Green (1922-1987) does not get caught in the
current version of this test but |first=(1888) is caught.
returns nothing
]]
local function name_is_numeric (name, list_name)
if utilities.is_set (name) then
if mw.ustring.match (name, '^[%A]+$') then -- when name does not contain any letters
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
returns nothing
]]
local function name_has_mult_names (name, list_name)
local _, commas, semicolons, nbsps;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if 1 < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value, wiki)
local test_val;
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter (last only)
name_is_numeric (last, list_name); -- check for names that are composed of digits and punctuation
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_is_numeric (first, list_name); -- check for names that are composed of digits and punctuation
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
local result;
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_code_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_code_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_code_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = {}; -- table made from the value assigned to |language=
local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
-- utilities.add_prop_cat ('foreign-lang-source', {name, lang_subtag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
name = ''; -- so we can reuse it
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or 'citation' == cite_class then
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors']; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
]]
local function get_display_names (max, count, list_name, etal, param)
if utilities.is_set (max) then
if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if max >= count then -- if |display-xxxxors= value greater than or equal to number of authors/editors
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive).
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local patterns = 'v' == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns;
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (patterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirstTable = {}
lastfirstTable = mw.text.split(v_name, "%s+")
first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove(lastfirstTable); -- get what should be the initials from the table
end
last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
local err_name;
if 'AuthorList' == list_name then -- figure out which name should be used in error message
err_name = 'author';
else
err_name = 'editor';
end
utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------
returns the concatenation of the formatted volume and issue parameters as a single string; or formatted volume
or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, cite_class, origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
if utilities.is_set (issue) then
return vol .. utilities.substitute (cfg.messages['j-issue'], issue);
end
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
]=]
local function archive_url_check (url, date)
local err_msg = ''; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date; -- return ArchiveURL and ArchiveDate
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date; -- preview mode so return ArchiveURL and ArchiveDate
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
local i
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, args.vauthors, 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |authors=
if 'authors' == A:ORIGIN('Authors') then -- but add a maint cat if the parameter is |authors=
utilities.set_message ('maint_authors'); -- because use of this parameter is discouraged; what to do about the aliases is a TODO:
end
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then
Contribution = Chapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = '';
if utilities.is_set (Periodical) then
Periodical_origin = A:ORIGIN('Periodical'); -- get the name of the periodical parameter
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. ' and ' .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
local ScriptPeriodical = A['ScriptPeriodical'];
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = utilities.hyphen_to_dash (A['Issue']);
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = utilities.hyphen_to_dash (A['Issue']);
end
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
local Page;
local Pages;
local At;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
end
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) then
local i = 0;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if utilities.in_array (this_page.nsText, cfg.uncategorized_namespaces) then
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different
utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together
if PublicationPlace == Place then
Place = ''; -- unset; don't need both if they are the same
end
elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title=
|encyclopedia= and |article= then map |encyclopedia= to |title=
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
if utilities.is_set (Encyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
Encyclopedia = nil; -- unset because not supported by this template
end
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', A:ORIGIN ('Encyclopedia')) .. ' and ' .. utilities.wrap_style ('parameter', Periodical_origin)});
end
if utilities.is_set (Encyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia; allow periodical without encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
end
if utilities.is_set (Periodical) then -- Periodical is set when |encyclopedia= is set
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= to |article= and |encyclopedia= to |title=
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
Title = Periodical;
ChapterFormat = Format;
Periodical = ''; -- redundant so unset
TransTitle = '';
URL = '';
Format = '';
TitleLink = '';
ScriptTitle = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title=
Periodical = ''; -- redundant so unset
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. ' and ' .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
-- CS1/2 mode
local Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], '');
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
-- controls capitalization of certain static text
local use_lowercase = ( sepc == ',' );
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
if utilities.is_set (Chapter) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. ' and ' .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message
end
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map');
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. ' and ' .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
-- legacy: promote PublicationDate to Date if neither Date nor Year are set.
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local PublicationDate = A['PublicationDate'];
local Year = A['Year'];
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promote PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
end
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local LayDate = A['LayDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables error_message, date_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
local date_parameters_list = {
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['lay-date'] = {val = LayDate, name = A:ORIGIN ('LayDate')},
['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
-- start temporary Julian / Gregorian calendar uncertainty categorization
if COinS_date.inter_cal_cat then
utilities.add_prop_cat ('jul-greg-uncertainty');
end
-- end temporary Julian / Gregorian calendar uncertainty categorization
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
LayDate = date_parameters_list['lay-date'].val;
PublicationDate = date_parameters_list['publication-date'].val;
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
local ID_list = {}; -- sequence table of rendered identifiers
local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list) then
if not utilities.is_set (ID_list_coins[config.CitationClass:upper()]) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv= & |citeseerx= required for their templates
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
local QuotePage = A['QuotePage'];
local QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date has correctly formatted date if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron or (not COinS_date.rftdate and Date) or '', -- chron but if not set and invalid date format use Date; keep this last bit?
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal;
local Translators; -- assembled translators name list
local translator_etal;
local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs
t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = {};
interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal;
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
control.maximum , editor_etal = get_display_names (A['DisplayEditors'], #e, 'editors', editor_etal, A:ORIGIN ('DisplayEditors'));
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
control.maximum, interviewer_etal = get_display_names (A['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, A:ORIGIN ('DisplayInterviewers'));
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
control.maximum, translator_etal = get_display_names (A['DisplayTranslators'], #t, 'translators', translator_etal, A:ORIGIN ('DisplayTranslators'));
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
control.maximum, contributor_etal = get_display_names (A['DisplayContributors'], #c, 'contributors', contributor_etal, A:ORIGIN ('DisplayContributors'));
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
control.maximum, author_etal = get_display_names (A['DisplayAuthors'], #a, 'authors', author_etal, A:ORIGIN ('DisplayAuthors'));
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
-- special case for chapter format so no error message or cat when chapter not supported
if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
end
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
utilities.set_message ('err_cite_web_url');
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = '';
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = "";
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
if utilities.is_set (Place) then
Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " ";
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. ' and ' .. utilities.wrap_style ('parameter', 'time')});
end
Position = " " .. Minutes .. " " .. cfg.messages['minutes'];
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cfg.messages['event'];
if sepc ~= '.' then
TimeCaption = TimeCaption:lower();
end
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'];
Agency = utilities.is_set (Agency) and wrap_msg ('agency', {sepc, Agency}) or "";
Volume = format_volume_issue (Volume, Issue, config.CitationClass, Periodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved']
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
local Quote = A['Quote'];
local TransQuote = A['TransQuote'];
local ScriptQuote = A['ScriptQuote'];
if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then
if utilities.is_set (Quote) then
if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
Quote = Quote:sub(2, -2); -- strip them off
end
end
Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags
if utilities.is_set (ScriptQuote) then
Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (TransQuote) then
if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
TransQuote = TransQuote:sub(2, -2); -- strip them off
end
Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote );
end
if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (QuotePage) then
extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not NoPP then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', '';
end
elseif utilities.is_set (QuotePages) then
extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', '';
elseif not NoPP then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', '';
end
end
Quote = quote_prefix .. ": " .. Quote;
else
Quote = sepc .. " " .. Quote;
end
PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
local arch_text;
if not utilities.is_set (ArchiveDate) then
utilities.set_message ('err_archive_missing_date');
ArchiveDate = ''; -- empty string for concatenation
end
if "live" == UrlStatus then
arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
arch_text = cfg.messages['archived-unfit'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.set_message ('maint_unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. " " .. utilities.substitute ( arch_text,
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
arch_text = cfg.messages['archived-missing'];
if sepc ~= "." then arch_text = arch_text:lower() end
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local Lay = '';
local LaySource = A['LaySource'];
local LayURL = A['LayURL'];
local LayFormat = A['LayFormat'];
LayFormat = style_format (LayFormat, LayURL, 'lay-format', 'lay-url');
if utilities.is_set (LayURL) then
if utilities.is_set (LayDate) then LayDate = " (" .. LayDate .. ")" end
if utilities.is_set (LaySource) then
LaySource = " – ''" .. utilities.safe_for_italics (LaySource) .. "''";
else
LaySource = "";
end
if sepc == '.' then
Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate
else
Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate
end
elseif utilities.is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url=
Lay = sepc .. LayFormat; -- if set and LayURL not set, then LayFormat has error message
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher;
if utilities.is_set (PublicationDate) then
PublicationDate = wrap_msg ('published', PublicationDate);
end
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
else
Publisher = PublicationDate;
end
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
if utilities.is_set (Others) then Others = safe_join ({Others, sepc .. " "}, sepc) end -- add terminal punctuation & space; check for dup sepc; TODO why do we need to do this here?
tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc );
elseif utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join( {Title, TitleNote}, sepc ); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join( {Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
else
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
else -- a sheet or stand-alone map
tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc );
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join( {Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc );
else -- all other CS1 templates
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language,
Volume, Others, Edition, Publisher, Agency}, sepc );
end
if #ID_list > 0 then
ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
else
ID_list = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Lay, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Lay, Quote }, sepc );
end
local text;
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = " ";
local post_text = "";
if utilities.is_set (Chapter) and 0 == #c then
in_text = in_text .. cfg.messages['in'] .. " "
if (sepc ~= '.') then
in_text = in_text:lower() -- lowercase for cs2
end
end
if EditorCount <= 1 then
post_text = " (" .. cfg.messages['editor'] .. ")"; -- be consistent with no-author, no-date case
else
post_text = " (" .. cfg.messages['editors'] .. ")";
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. ", " .. cfg.messages['editor'];
else
Editors = Editors .. ", " .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
text = text:sub(1, -sepc:len() - 1);
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
local citeref_id;
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
options_t.id = Ref or citeref_id;
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass);
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v));
end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local name = tostring (name);
local enum_name; -- for enumerated parameters, is name with enumerator replaced with '#'
local state;
local function state_test (state, name) -- local function to do testing of state values
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted
return nil;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list ) then -- limited parameter sets allowed for these templates
state = whitelist.limited_basic_arguments[name];
if true == state_test (state, name) then return true; end
state = whitelist.preprint_arguments[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test (state, name) then return true; end
-- limited enumerated parameters list
enum_name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
state = whitelist.limited_numbered_arguments[enum_name];
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list) then -- experiment for template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test (state, name) then return true; end
end -- if here, fall into general validation
state = whitelist.basic_arguments[name]; -- all other templates; all normal parameters allowed
if true == state_test (state, name) then return true; end
-- all enumerated parameters allowed
enum_name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
state = whitelist.numbered_arguments[enum_name];
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (url_param_t)
local url_error_t = {};
check_for_url (url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
This is used by templates such as {{cite book}} to create the actual citation text.
]]
local function citation(frame)
Frame = frame; -- save a copy in case we need to display an error message in preview mode
local sandbox = '/sandbox' -- i18n: replace this rvalue with the name that your wiki uses to identify sandbox subpages
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
local pframe = frame:getParent()
local styles;
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css';
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local args = {}; -- table where we store all of the template's arguments
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local config = {}; -- table to store parameters from the module {{#invoke:}}
for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame
config[k] = v;
-- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if ('string' == type (k)) then
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9
end
if not validate( k, config.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
if is_sandbox then -- did the {{#invoke:}} use sandbox version?
suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions/sandbox' ); -- use the sandbox version
else
suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions' ); -- use the live version
end
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
args[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
-- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep?
-- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that)
-- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here
end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact?
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local url_param_t = {};
for k, v in pairs( args ) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table
url_param_t[k] = v; -- make a parameter/value list for extraneous url check
end
end
has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong
return table.concat ({
frame:extensionTag ('templatestyles', '', {src=styles}),
citation0( config, args)
});
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {citation = citation};
5b914afd20bdaa8daab7192c9ee32f246e5bee9b
Module:Citation/CS1/Configuration
828
51
118
117
2022-09-04T15:24:34Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local lang_obj = mw.language.getContentLanguage(); -- make a language object for the local language; used here for languages and dates
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E S >------------------------------
List of namespaces that should not be included in citation error categories.
Same as setting notracking = true by default.
Note: Namespace names should use underscores instead of spaces.
]]
local uncategorized_namespaces = { 'User', 'Talk', 'User_talk', 'Wikipedia_talk',
'File_talk', 'Template_talk', 'Help_talk', 'Category_talk', 'Portal_talk',
'Book_talk', 'Draft_talk', 'Education_Program_talk', 'Module_talk', 'MediaWiki_talk' };
local uncategorized_subpages = {'/[Ss]andbox', '/[Tt]estcases', '/[^/]*[Ll]og', '/[Aa]rchive'}; -- list of Lua patterns found in page names of pages we should not categorize
--[[--------------------------< M E S S A G E S >--------------------------------------------------------------
Translation table
The following contains fixed text that may be output as part of a citation.
This is separated from the main body to aid in future translations of this
module.
]]
local messages = {
['agency'] = '$1 $2', -- $1 is sepc, $2 is agency
['archived-dead'] = 'Archived from $1 on $2',
['archived-live'] = '$1 from the original on $2',
['archived-missing'] = 'Archived from the original$1 on $2',
['archived-unfit'] = 'Archived from the original on ',
['archived'] = 'Archived',
['by'] = 'By', -- contributions to authored works: introduction, foreword, afterword
['cartography'] = 'Cartography by $1',
['editor'] = 'ed.',
['editors'] = 'eds.',
['edition'] = '($1 ed.)',
['episode'] = 'Episode $1',
['et al'] = 'et al.',
['in'] = 'In', -- edited works
['inactive'] = 'inactive',
['inset'] = '$1 inset',
['interview'] = 'Interviewed by $1',
['lay summary'] = 'Lay summary',
['mismatch'] = '<code class="cs1-code">|$1=</code> / <code class="cs1-code">|$2=</code> mismatch', -- $1 is year param name; $2 is date param name
['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]: $1',
['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none
['original'] = 'the original',
['origdate'] = ' [$1]',
['published'] = ' (published $1)',
['retrieved'] = 'Retrieved $1',
['season'] = 'Season $1',
['section'] = '§ $1',
['sections'] = '§§ $1',
['series'] = '$1 $2', -- $1 is sepc, $2 is series
['seriesnum'] = 'Series $1',
['translated'] = 'Translated by $1',
['type'] = ' ($1)', -- for titletype
['written'] = 'Written at $1',
['vol'] = '$1 Vol. $2', -- $1 is sepc; bold journal style volume is in presentation{}
['vol-no'] = '$1 Vol. $2, no. $3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization)
['issue'] = '$1 No. $2', -- $1 is sepc
['j-vol'] = '$1 $2', -- sepc, volume; bold journal volume is in presentation{}
['j-issue'] = ' ($1)',
['nopp'] = '$1 $2'; -- page(s) without prefix; $1 is sepc
['p-prefix'] = "$1 p. $2", -- $1 is sepc
['pp-prefix'] = "$1 pp. $2", -- $1 is sepc
['j-page(s)'] = ': $1', -- same for page and pages
['sheet'] = '$1 Sheet $2', -- $1 is sepc
['sheets'] = '$1 Sheets $2', -- $1 is sepc
['j-sheet'] = ': Sheet $1',
['j-sheets'] = ': Sheets $1',
['language'] = '(in $1)',
['via'] = " – via $1",
['event'] = 'Event occurs at',
['minutes'] = 'minutes in',
-- Determines the location of the help page
['help page link'] = 'Help:CS1 errors',
['help page label'] = 'help',
-- categories
['cat wikilink'] = '[[Category:$1]]', -- $1 is the category name
[':cat wikilink'] = '[[:Category:$1|link]]', -- category name as maintenance message wikilink; $1 is the category name
-- Internal errors (should only occur if configuration is bad)
['undefined_error'] = 'Called with an undefined error condition',
['unknown_ID_key'] = 'Unrecognized ID key: ', -- an ID key in id_handlers not found in ~/Identifiers func_map{}
['unknown_ID_access'] = 'Unrecognized ID access keyword: ', -- an ID access keyword in id_handlers not found in keywords_lists['id-access']{}
['unknown_argument_map'] = 'Argument map not defined for this variable',
['bare_url_no_origin'] = 'Bare URL found but origin indicator is nil or empty',
['warning_msg_e'] = '<span style="color:#d33">One or more <code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code> templates have errors</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link
['warning_msg_m'] = '<span style="color:#3a3">One or more <code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code> templates have maintenance messages</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link
}
--[[--------------------------< C I T A T I O N _ C L A S S _ M A P >------------------------------------------
this table maps the value assigned to |CitationClass= in the cs1|2 templates to the canonical template name when
the value assigned to |CitationClass= is different from the canonical template name. |CitationClass= values are
used as class attributes in the <cite> tag that encloses the citation so these names may not contain spaces while
the canonical template name may. These names are used in warning_msg_e and warning_msg_m to create links to the
template's documentation when an article is displayed in preivew mode.
Most cs1|2 template |CitationClass= values at en.wiki match their canonical template names so are not listed here.
]]
local citation_class_map_t = { -- TODO: if kept, these and all other config.CitationClass 'names' require some sort of i18n
['audio-visual'] = 'AV media', -- TODO: move to ~/Configuration
['AV-media-notes'] = 'AV media notes',
['encyclopaedia'] = 'encyclopedia',
['mailinglist'] = 'mailing list',
['pressrelease'] = 'press release'
}
--[=[-------------------------< E T _ A L _ P A T T E R N S >--------------------------------------------------
This table provides Lua patterns for the phrase "et al" and variants in name text
(author, editor, etc.). The main module uses these to identify and emit the 'etal' message.
]=]
local et_al_patterns = {
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][%.;,\"']*$", -- variations on the 'et al' theme
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][Ii][AaIi][Ee]?[%.;,\"']*$", -- variations on the 'et alia', 'et alii' and 'et aliae' themes (false positive 'et aliie' unlikely to match)
"[;,]? *%f[%a]and [Oo]thers", -- an alternative to et al.
"%[%[ *[Ee][Tt]%.? *[Aa][Ll]%.? *%]%]", -- a wikilinked form
"%(%( *[Ee][Tt]%.? *[Aa][Ll]%.? *%)%)", -- a double-bracketed form (to counter partial removal of ((...)) syntax)
"[%(%[] *[Ee][Tt]%.? *[Aa][Ll]%.? *[%)%]]", -- a bracketed form
}
--[[--------------------------< P R E S E N T A T I O N >------------------------
Fixed presentation markup. Originally part of citation_config.messages it has
been moved into its own, more semantically correct place.
]]
local presentation =
{
-- .citation-comment class is specified at Help:CS1_errors#Controlling_error_message_display
['hidden-error'] = '<span class="cs1-hidden-error citation-comment">$1</span>',
['visible-error'] = '<span class="cs1-visible-error citation-comment">$1</span>',
['hidden-maint'] = '<span class="cs1-maint citation-comment">$1</span>',
['accessdate'] = '<span class="reference-accessdate">$1$2</span>', -- to allow editors to hide accessdate using personal CSS
['bdi'] = '<bdi$1>$2</bdi>', -- bidirectional isolation used with |script-title= and the like
['cite'] = '<cite class="$1">$2</cite>'; -- for use when citation does not have a namelist and |ref= not set so no id="..." attribute
['cite-id'] = '<cite id="$1" class="$2">$3</cite>'; -- for use when when |ref= is set or when citation has a namelist
['format'] = ' <span class="cs1-format">($1)</span>', -- for |format=, |chapter-format=, etc.
-- various access levels, for |access=, |doi-access=, |arxiv=, ...
-- narrow no-break space   may work better than nowrap CSS. Or not? Browser support?
['ext-link-access-signal'] = '<span class="$1" title="$2">$3</span>', -- external link with appropriate lock icon
['free'] = {class='cs1-lock-free', title='Freely accessible'}, -- classes defined in Module:Citation/CS1/styles.css
['registration'] = {class='cs1-lock-registration', title='Free registration required'},
['limited'] = {class='cs1-lock-limited', title='Free access subject to limited trial, subscription normally required'},
['subscription'] = {class='cs1-lock-subscription', title='Paid subscription required'},
['interwiki-icon'] = '<span class="$1" title="$2">$3</span>',
['class-wikisource'] = 'cs1-ws-icon',
['italic-title'] = "''$1''",
['kern-left'] = '<span class="cs1-kern-left"></span>$1', -- spacing to use when title contains leading single or double quote mark
['kern-right'] = '$1<span class="cs1-kern-right"></span>', -- spacing to use when title contains trailing single or double quote mark
['nowrap1'] = '<span class="nowrap">$1</span>', -- for nowrapping an item: <span ...>yyyy-mm-dd</span>
['nowrap2'] = '<span class="nowrap">$1</span> $2', -- for nowrapping portions of an item: <span ...>dd mmmm</span> yyyy (note white space)
['ocins'] = '<span title="$1" class="Z3988"></span>',
['parameter'] = '<code class="cs1-code">|$1=</code>',
['ps_cs1'] = '.'; -- CS1 style postscript (terminal) character
['ps_cs2'] = ''; -- CS2 style postscript (terminal) character (empty string)
['quoted-text'] = '<q>$1</q>', -- for wrapping |quote= content
['quoted-title'] = '"$1"',
['sep_cs1'] = '.', -- CS1 element separator
['sep_cs2'] = ',', -- CS2 separator
['sep_nl'] = ';', -- CS1|2 style name-list separator between names is a semicolon
['sep_nl_and'] = ' and ', -- used as last nl sep when |name-list-style=and and list has 2 items
['sep_nl_end'] = '; and ', -- used as last nl sep when |name-list-style=and and list has 3+ names
['sep_name'] = ', ', -- CS1|2 style last/first separator is <comma><space>
['sep_nl_vanc'] = ',', -- Vancouver style name-list separator between authors is a comma
['sep_name_vanc'] = ' ', -- Vancouver style last/first separator is a space
['sep_list'] = ', ', -- used for |language= when list has 3+ items except for last sep which uses sep_list_end
['sep_list_pair'] = ' and ', -- used for |language= when list has 2 items
['sep_list_end'] = ', and ', -- used as last list sep for |language= when list has 3+ items
['trans-italic-title'] = "[''$1'']",
['trans-quoted-title'] = "[$1]", -- for |trans-title= and |trans-quote=
['vol-bold'] = '$1 <b>$2</b>', -- sepc, volume; for bold journal cites; for other cites ['vol'] in messages{}
}
--[[--------------------------< A L I A S E S >---------------------------------
Aliases table for commonly passed parameters.
Parameter names on the right side in the assignments in this table must have been
defined in the Whitelist before they will be recognized as valid parameter names
]]
local aliases = {
['AccessDate'] = {'access-date', 'accessdate'}, -- Used by InternetArchiveBot
['Agency'] = 'agency',
['ArchiveDate'] = {'archive-date', 'archivedate'}, -- Used by InternetArchiveBot
['ArchiveFormat'] = 'archive-format',
['ArchiveURL'] = {'archive-url', 'archiveurl'}, -- Used by InternetArchiveBot
['ASINTLD'] = 'asin-tld',
['At'] = 'at', -- Used by InternetArchiveBot
['Authors'] = {'authors', 'people', 'credits'},
['BookTitle'] = {'book-title', 'booktitle'},
['Cartography'] = 'cartography',
['Chapter'] = {'chapter', 'contribution', 'entry', 'article', 'section'},
['ChapterFormat'] = {'chapter-format', 'contribution-format', 'entry-format',
'article-format', 'section-format'};
['ChapterURL'] = {'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url', 'chapterurl'}, -- Used by InternetArchiveBot
['ChapterUrlAccess'] = {'chapter-url-access', 'contribution-url-access',
'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot
['Class'] = 'class', -- cite arxiv and arxiv identifier
['Collaboration'] = 'collaboration',
['Conference'] = {'conference', 'event'},
['ConferenceFormat'] = 'conference-format',
['ConferenceURL'] = 'conference-url', -- Used by InternetArchiveBot
['Date'] = {'date', 'air-date', 'airdate'}, -- air-date and airdate for cite episode and cite serial only
['Degree'] = 'degree',
['DF'] = 'df',
['DisplayAuthors'] = {'display-authors', 'display-subjects'},
['DisplayContributors'] = 'display-contributors',
['DisplayEditors'] = 'display-editors',
['DisplayInterviewers'] = 'display-interviewers',
['DisplayTranslators'] = 'display-translators',
['Docket'] = 'docket',
['DoiBroken'] = 'doi-broken-date',
['Edition'] = 'edition',
['Embargo'] = 'pmc-embargo-date',
['Encyclopedia'] = {'encyclopedia', 'encyclopaedia', 'dictionary'}, -- cite encyclopedia only
['Episode'] = 'episode', -- cite serial only TODO: make available to cite episode?
['Format'] = 'format',
['ID'] = {'id', 'ID'},
['Inset'] = 'inset',
['Issue'] = {'issue', 'number'},
['Language'] = {'language', 'lang'},
['LayDate'] = 'lay-date',
['LayFormat'] = 'lay-format',
['LaySource'] = 'lay-source',
['LayURL'] = 'lay-url',
['MailingList'] = {'mailing-list', 'mailinglist'}, -- cite mailing list only
['Map'] = 'map', -- cite map only
['MapFormat'] = 'map-format', -- cite map only
['MapURL'] = {'map-url', 'mapurl'}, -- cite map only -- Used by InternetArchiveBot
['MapUrlAccess'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot
['Minutes'] = 'minutes',
['Mode'] = 'mode',
['NameListStyle'] = 'name-list-style',
['Network'] = 'network',
['Newsgroup'] = 'newsgroup', -- cite newsgroup only
['NoPP'] = {'no-pp', 'nopp'},
['NoTracking'] = {'no-tracking', 'template-doc-demo'},
['Number'] = 'number', -- this case only for cite techreport
['OrigDate'] = {'orig-date', 'orig-year', 'origyear'},
['Others'] = 'others',
['Page'] = {'page', 'p'}, -- Used by InternetArchiveBot
['Pages'] = {'pages', 'pp'}, -- Used by InternetArchiveBot
['Periodical'] = {'journal', 'magazine', 'newspaper', 'periodical', 'website', 'work'},
['Place'] = {'place', 'location'},
['PostScript'] = 'postscript',
['PublicationDate'] = {'publication-date', 'publicationdate'},
['PublicationPlace'] = {'publication-place', 'publicationplace'},
['PublisherName'] = {'publisher', 'institution'},
['Quote'] = {'quote', 'quotation'},
['QuotePage'] = 'quote-page',
['QuotePages'] = 'quote-pages',
['Ref'] = 'ref',
['Scale'] = 'scale',
['ScriptChapter'] = {'script-chapter', 'script-contribution', 'script-entry',
'script-article', 'script-section'},
['ScriptMap'] = 'script-map',
['ScriptPeriodical'] = {'script-journal', 'script-magazine', 'script-newspaper',
'script-periodical', 'script-website', 'script-work'},
['ScriptQuote'] = 'script-quote',
['ScriptTitle'] = 'script-title', -- Used by InternetArchiveBot
['Season'] = 'season',
['Sections'] = 'sections', -- cite map only
['Series'] = {'series', 'version'},
['SeriesLink'] = {'series-link', 'serieslink'},
['SeriesNumber'] = {'series-number', 'series-no'},
['Sheet'] = 'sheet', -- cite map only
['Sheets'] = 'sheets', -- cite map only
['Station'] = 'station',
['Time'] = 'time',
['TimeCaption'] = 'time-caption',
['Title'] = 'title', -- Used by InternetArchiveBot
['TitleLink'] = {'title-link', 'episode-link', 'episodelink'}, -- Used by InternetArchiveBot
['TitleNote'] = 'department',
['TitleType'] = {'type', 'medium'},
['TransChapter'] = {'trans-article', 'trans-chapter', 'trans-contribution',
'trans-entry', 'trans-section'},
['Transcript'] = 'transcript',
['TranscriptFormat'] = 'transcript-format',
['TranscriptURL'] = {'transcript-url', 'transcripturl'}, -- Used by InternetArchiveBot
['TransMap'] = 'trans-map', -- cite map only
['TransPeriodical'] = {'trans-journal', 'trans-magazine', 'trans-newspaper',
'trans-periodical', 'trans-website', 'trans-work'},
['TransQuote'] = 'trans-quote',
['TransTitle'] = 'trans-title', -- Used by InternetArchiveBot
['URL'] = {'url', 'URL'}, -- Used by InternetArchiveBot
['UrlAccess'] = 'url-access', -- Used by InternetArchiveBot
['UrlStatus'] = 'url-status', -- Used by InternetArchiveBot
['Vauthors'] = 'vauthors',
['Veditors'] = 'veditors',
['Via'] = 'via',
['Volume'] = 'volume',
['Year'] = 'year',
['AuthorList-First'] = {"first#", "author-first#", "author#-first", "given#",
"author-given#", "author#-given"},
['AuthorList-Last'] = {"last#", "author-last#", "author#-last", "surname#",
"author-surname#", "author#-surname", "author#", "subject#", 'host#'},
['AuthorList-Link'] = {"author-link#", "author#-link", "subject-link#",
"subject#-link", "authorlink#", "author#link"},
['AuthorList-Mask'] = {"author-mask#", "author#-mask", "subject-mask#", "subject#-mask"},
['ContributorList-First'] = {'contributor-first#', 'contributor#-first',
'contributor-given#', 'contributor#-given'},
['ContributorList-Last'] = {'contributor-last#', 'contributor#-last',
'contributor-surname#', 'contributor#-surname', 'contributor#'},
['ContributorList-Link'] = {'contributor-link#', 'contributor#-link'},
['ContributorList-Mask'] = {'contributor-mask#', 'contributor#-mask'},
['EditorList-First'] = {"editor-first#", "editor#-first", "editor-given#", "editor#-given"},
['EditorList-Last'] = {"editor-last#", "editor#-last", "editor-surname#",
"editor#-surname", "editor#"},
['EditorList-Link'] = {"editor-link#", "editor#-link"},
['EditorList-Mask'] = {"editor-mask#", "editor#-mask"},
['InterviewerList-First'] = {'interviewer-first#', 'interviewer#-first',
'interviewer-given#', 'interviewer#-given'},
['InterviewerList-Last'] = {'interviewer-last#', 'interviewer#-last',
'interviewer-surname#', 'interviewer#-surname', 'interviewer#'},
['InterviewerList-Link'] = {'interviewer-link#', 'interviewer#-link'},
['InterviewerList-Mask'] = {'interviewer-mask#', 'interviewer#-mask'},
['TranslatorList-First'] = {'translator-first#', 'translator#-first',
'translator-given#', 'translator#-given'},
['TranslatorList-Last'] = {'translator-last#', 'translator#-last',
'translator-surname#', 'translator#-surname', 'translator#'},
['TranslatorList-Link'] = {'translator-link#', 'translator#-link'},
['TranslatorList-Mask'] = {'translator-mask#', 'translator#-mask'},
}
--[[--------------------------< P U N C T _ S K I P >---------------------------
builds a table of parameter names that the extraneous terminal punctuation check should not check.
]]
local punct_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'BookTitle', 'Chapter', 'ScriptChapter', 'ScriptTitle', 'Title', 'TransChapter', 'Transcript', 'TransMap', 'TransTitle', -- title-holding parameters
'AuthorList-Mask', 'ContributorList-Mask', 'EditorList-Mask', 'InterviewerList-Mask', 'TranslatorList-Mask', -- name-list mask may have name separators
'PostScript', 'Quote', 'ScriptQuote', 'TransQuote', 'Ref', -- miscellaneous
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'LayURL', 'MapURL', 'TranscriptURL', 'URL', -- URL-holding parameters
}
local url_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'ID', 'LayURL', 'MapURL', 'TranscriptURL', 'URL', -- parameters allowed to hold urls
'Page', 'Pages', 'At', 'QuotePage', 'QuotePages', -- insource locators allowed to hold urls
}
local function build_skip_table (skip_t, meta_params)
for _, meta_param in ipairs (meta_params) do -- for each meta parameter key
local params = aliases[meta_param]; -- get the parameter or the table of parameters associated with the meta parameter name
if 'string' == type (params) then
skip_t[params] = 1; -- just a single parameter
else
for _, param in ipairs (params) do -- get the parameter name
skip_t[param] = 1; -- add the parameter name to the skip table
local count;
param, count = param:gsub ('#', ''); -- remove enumerator marker from enumerated parameters
if 0 ~= count then -- if removed
skip_t[param] = 1; -- add param name without enumerator marker
end
end
end
end
return skip_t;
end
local punct_skip = {};
local url_skip = {};
--[[-----------< S P E C I A L C A S E T R A N S L A T I O N S >------------
This table is primarily here to support internationalization. Translations in
this table are used, for example, when an error message, category name, etc.,
is extracted from the English alias key. There may be other cases where
this translation table may be useful.
]]
local is_Latn = 'A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143';
local special_case_translation = {
['AuthorList'] = 'authors list', -- used to assemble maintenance category names
['ContributorList'] = 'contributors list', -- translation of these names plus translation of the base mainenance category names in maint_cats{} table below
['EditorList'] = 'editors list', -- must match the names of the actual categories
['InterviewerList'] = 'interviewers list', -- this group or translations used by name_has_ed_markup() and name_has_mult_names()
['TranslatorList'] = 'translators list',
-- Lua patterns to match pseudo-titles used by InternetArchiveBot and others as placeholder for unknown |title= value
['archived_copy'] = { -- used with CS1 maint: Archive[d] copy as title
['en'] = '^archived?%s+copy$', -- for English; translators: keep this because templates imported from en.wiki
['local'] = nil, -- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
},
-- Lua patterns to match generic titles; usually created by bots or reference filling tools
-- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
-- generic titles and patterns in this table should be lowercase only
-- leave ['local'] nil except when there is a matching generic title in your language
-- boolean 'true' for plain-text searches; 'false' for pattern searches
['generic_titles'] = {
['accept'] = {
},
['reject'] = {
{['en'] = {'^wayback%s+machine$', false}, ['local'] = nil},
{['en'] = {'are you a robot', true}, ['local'] = nil},
{['en'] = {'hugedomains.com', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?no +title[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'page not found', true}, ['local'] = nil},
{['en'] = {'subscribe to read', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?unknown[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'website is for sale', true}, ['local'] = nil},
{['en'] = {'^404', false}, ['local'] = nil},
{['en'] = {'internet archive wayback machine', true}, ['local'] = nil},
{['en'] = {'log into facebook', true}, ['local'] = nil},
{['en'] = {'login • instagram', true}, ['local'] = nil},
{['en'] = {'redirecting...', true}, ['local'] = nil},
{['en'] = {'usurped title', true}, ['local'] = nil}, -- added by a GreenC bot
{['en'] = {'webcite query result', true}, ['local'] = nil},
{['en'] = {'wikiwix\'s cache', true}, ['local'] = nil},
}
},
-- boolean 'true' for plain-text searches, search string must be lowercase only
-- boolean 'false' for pattern searches
-- leave ['local'] nil except when there is a matching generic name in your language
['generic_names'] = {
['accept'] = {
{['en'] = {'%[%[[^|]*%(author%) *|[^%]]*%]%]', false}, ['local'] = nil},
},
['reject'] = {
{['en'] = {'about us', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]dvisor%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]uthor%f[%A]', false}, ['local'] = nil},
{['en'] = {'collaborator', true}, ['local'] = nil},
{['en'] = {'contributor', true}, ['local'] = nil},
{['en'] = {'contact us', true}, ['local'] = nil},
{['en'] = {'directory', true}, ['local'] = nil},
{['en'] = {'%f[%(%[][%(%[]%s*eds?%.?%s*[%)%]]?$', false}, ['local'] = nil},
{['en'] = {'[,%.%s]%f[e]eds?%.?$', false}, ['local'] = nil},
{['en'] = {'^eds?[%.,;]', false}, ['local'] = nil},
{['en'] = {'^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]dited%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]ditors?%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a]]Ee]mail%f[%A]', false}, ['local'] = nil},
{['en'] = {'facebook', true}, ['local'] = nil},
{['en'] = {'google', true}, ['local'] = nil},
{['en'] = {'home page', true}, ['local'] = nil},
{['en'] = {'instagram', true}, ['local'] = nil},
{['en'] = {'interviewer', true}, ['local'] = nil},
{['en'] = {'linkedIn', true}, ['local'] = nil},
{['en'] = {'^[Nn]ews$', false}, ['local'] = nil},
{['en'] = {'pinterest', true}, ['local'] = nil},
{['en'] = {'policy', true}, ['local'] = nil},
{['en'] = {'privacy', true}, ['local'] = nil},
{['en'] = {'translator', true}, ['local'] = nil},
{['en'] = {'tumblr', true}, ['local'] = nil},
{['en'] = {'twitter', true}, ['local'] = nil},
{['en'] = {'site name', true}, ['local'] = nil},
{['en'] = {'statement', true}, ['local'] = nil},
{['en'] = {'submitted', true}, ['local'] = nil},
{['en'] = {'super.?user', false}, ['local'] = nil},
{['en'] = {'%f['..is_Latn..'][Uu]ser%f[^'..is_Latn..']', false}, ['local'] = nil},
{['en'] = {'verfasser', true}, ['local'] = nil},
}
}
}
--[[--------------------------< D A T E _ N A M E S >----------------------------------------------------------
This table of tables lists local language date names and fallback English date names.
The code in Date_validation will look first in the local table for valid date names.
If date names are not found in the local table, the code will look in the English table.
Because citations can be copied to the local wiki from en.wiki, the English is
required when the date-name translation function date_name_xlate() is used.
In these tables, season numbering is defined by
Extended Date/Time Format (EDTF) Specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard
defines various divisions using numbers 21-41. CS1|2 only supports generic seasons.
EDTF does support the distinction between north and south hemisphere seasons
but CS1|2 has no way to make that distinction.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
The standard does not address 'named' dates so, for the purposes of CS1|2,
Easter and Christmas are defined here as 98 and 99, which should be out of the
ISO 8601 (EDTF) range of uses for a while.
local_date_names_from_mediawiki is a boolean. When set to:
true – module will fetch local month names from MediaWiki for both date_names['local']['long'] and date_names['local']['short']
false – module will *not* fetch local month names from MediaWiki
Caveat lector: There is no guarantee that MediaWiki will provide short month names. At your wiki you can test
the results of the MediaWiki fetch in the debug console with this command (the result is alpha sorted):
=mw.dumpObject (p.date_names['local'])
While the module can fetch month names from MediaWiki, it cannot fetch the quarter, season, and named date names
from MediaWiki. Those must be translated manually.
]]
local local_date_names_from_mediawiki = true; -- when false, manual translation required for date_names['local']['long'] and date_names['local']['short']
-- when true, module fetches long and short month names from MediaWiki
local date_names = {
['en'] = { -- English
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
-- when local_date_names_from_mediawiki = false
['local'] = { -- replace these English date names with the local language equivalents
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
['inv_local_long'] = {}, -- used in date reformatting & translation; copy of date_names['local'].long where k/v are inverted: [1]='<local name>' etc.
['inv_local_short'] = {}, -- used in date reformatting & translation; copy of date_names['local'].short where k/v are inverted: [1]='<local name>' etc.
['inv_local_quarter'] = {}, -- used in date translation; copy of date_names['local'].quarter where k/v are inverted: [1]='<local name>' etc.
['inv_local_season'] = {}, -- used in date translation; copy of date_names['local'].season where k/v are inverted: [1]='<local name>' etc.
['inv_local_named'] = {}, -- used in date translation; copy of date_names['local'].named where k/v are inverted: [1]='<local name>' etc.
['local_digits'] = {['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4', ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9'}, -- used to convert local language digits to Western 0-9
['xlate_digits'] = {},
}
if local_date_names_from_mediawiki then -- if fetching local month names from MediaWiki is enabled
local long_t = {};
local short_t = {};
for i=1, 12 do -- loop 12x and
local name = lang_obj:formatDate('F', '2022-' .. i .. '-1'); -- get long month name for each i
long_t[name] = i; -- save it
name = lang_obj:formatDate('M', '2022-' .. i .. '-1'); -- get short month name for each i
short_t[name] = i; -- save it
end
date_names['local']['long'] = long_t; -- write the long table – overwrites manual translation
date_names['local']['short'] = short_t; -- write the short table – overwrites manual translation
end
-- create inverted date-name tables for reformatting and/or translation
for _, invert_t in pairs {{'long', 'inv_local_long'}, {'short', 'inv_local_short'}, {'quarter', 'inv_local_quarter'}, {'season', 'inv_local_season'}, {'named', 'inv_local_named'}} do
for name, i in pairs (date_names['local'][invert_t[1]]) do -- this table is ['name'] = i
date_names[invert_t[2]][i] = name; -- invert to get [i] = 'name' for conversions from ymd
end
end
for ld, ed in pairs (date_names.local_digits) do -- make a digit translation table for simple date translation from en to local language using local_digits table
date_names.xlate_digits [ed] = ld; -- en digit becomes index with local digit as the value
end
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}}
'{{ *[Uu]se +(dmy) +dates *[|}]', -- 1159k -- sorted by approximate transclusion count
'{{ *[Uu]se +(mdy) +dates *[|}]', -- 212k
'{{ *[Uu]se +(MDY) +dates *[|}]', -- 788
'{{ *[Uu]se +(DMY) +dates *[|}]', -- 343
'{{ *([Mm]dy) *[|}]', -- 176
'{{ *[Uu]se *(dmy) *[|}]', -- 156 + 18
'{{ *[Uu]se *(mdy) *[|}]', -- 149 + 11
'{{ *([Dd]my) *[|}]', -- 56
'{{ *[Uu]se +(MDY) *[|}]', -- 5
'{{ *([Dd]MY) *[|}]', -- 3
'{{ *[Uu]se(mdy)dates *[|}]', -- 1
'{{ *[Uu]se +(DMY) *[|}]', -- 0
'{{ *([Mm]DY) *[|}]', -- 0
}
local function get_date_format ()
local title_object = mw.title.getCurrentTitle();
if title_object.namespace == 10 then -- not in template space so that unused templates appear in unused-template-reports;
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
local content = title_object:getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects
local start, _, match = content:find(pattern); -- match is the three letters indicating desired date format
if match then
content = content:match ('%b{}', start); -- get the whole template
if content:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length
return match:lower() .. '-' .. content:match ('| *cs1%-dates *= *([lsy][sy]?)');
else
return match:lower() .. '-all'; -- no |cs1-dates= k/v pair; return value appropriate for use in |df=
end
end
end
end
local global_df;
--[[-----------------< V O L U M E , I S S U E , P A G E S >------------------
These tables hold cite class values (from the template invocation) and identify those templates that support
|volume=, |issue=, and |page(s)= parameters. Cite conference and cite map require further qualification which
is handled in the main module.
]]
local templates_using_volume = {'citation', 'audio-visual', 'book', 'conference', 'encyclopaedia', 'interview', 'journal', 'magazine', 'map', 'news', 'report', 'techreport', 'thesis'}
local templates_using_issue = {'citation', 'conference', 'episode', 'interview', 'journal', 'magazine', 'map', 'news', 'podcast'}
local templates_not_using_page = {'audio-visual', 'episode', 'mailinglist', 'newsgroup', 'podcast', 'serial', 'sign', 'speech'}
--[[
These tables control when it is appropriate for {{citation}} to render |volume= and/or |issue=. The parameter
names in the tables constrain {{citation}} so that its renderings match the renderings of the equivalent cs1
templates. For example, {{cite web}} does not support |volume= so the equivalent {{citation |website=...}} must
not support |volume=.
]]
local citation_no_volume_t = { -- {{citation}} does not render |volume= when these parameters are used
'website', 'mailinglist', 'script-website',
}
local citation_issue_t = { -- {{citation}} may render |issue= when these parameters are used
'journal', 'magazine', 'newspaper', 'periodical', 'work',
'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-work',
}
--[[
Patterns for finding extra text in |volume=, |issue=, |page=, |pages=
]]
local vol_iss_pg_patterns = {
good_ppattern = '^P[^%.PpGg]', -- OK to begin with uppercase P: P7 (page 7 of section P), but not p123 (page 123); TODO: this allows 'Pages' which it should not
bad_ppatterns = { -- patterns for |page= and |pages=
'^[Pp][PpGg]?%.?[ %d]',
'^[Pp][Pp]?%. ', -- from {{p.}} and {{pp.}} templates
'^[Pp]ages?',
'^[Pp]gs.?',
},
vpatterns = { -- patterns for |volume=
'^volumes?',
'^vols?[%.:=]?'
},
ipatterns = { -- patterns for |issue=
'^issues?',
'^iss[%.:=]?',
'^numbers?',
'^nos?%A', -- don't match 'november' or 'nostradamus'
'^nr[%.:=]?',
'^n[%.:= ]' -- might be a valid issue without separator (space char is sep char here)
}
}
--[[--------------------------< K E Y W O R D S >-------------------------------
These tables hold keywords for those parameters that have defined sets of acceptable keywords.
]]
--[[-------------------< K E Y W O R D S T A B L E >--------------------------
this is a list of keywords; each key in the list is associated with a table of
synonymous keywords possibly from different languages.
for I18N: add local-language keywords to value table; do not change the key.
For example, adding the German keyword 'ja':
['affirmative'] = {'yes', 'true', 'y', 'ja'},
Because CS1|2 templates from en.wiki articles are often copied to other local wikis,
it is recommended that the English keywords remain in these tables.
]]
local keywords = {
['amp'] = {'&', 'amp', 'ampersand'}, -- |name-list-style=
['and'] = {'and', 'serial'}, -- |name-list-style=
['affirmative'] = {'yes', 'true', 'y'}, -- |no-tracking=, |no-pp= -- Used by InternetArchiveBot
['afterword'] = {'afterword'}, -- |contribution=
['bot: unknown'] = {'bot: unknown'}, -- |url-status= -- Used by InternetArchiveBot
['cs1'] = {'cs1'}, -- |mode=
['cs2'] = {'cs2'}, -- |mode=
['dead'] = {'dead', 'deviated'}, -- |url-status= -- Used by InternetArchiveBot
['dmy'] = {'dmy'}, -- |df=
['dmy-all'] = {'dmy-all'}, -- |df=
['foreword'] = {'foreword'}, -- |contribution=
['free'] = {'free'}, -- |<id>-access= -- Used by InternetArchiveBot
['harv'] = {'harv'}, -- |ref=; this no longer supported; is_valid_parameter_value() called with <invert> = true
['introduction'] = {'introduction'}, -- |contribution=
['limited'] = {'limited'}, -- |url-access= -- Used by InternetArchiveBot
['live'] = {'live'}, -- |url-status= -- Used by InternetArchiveBot
['mdy'] = {'mdy'}, -- |df=
['mdy-all'] = {'mdy-all'}, -- |df=
['none'] = {'none'}, -- |postscript=, |ref=, |title=, |type= -- Used by InternetArchiveBot
['off'] = {'off'}, -- |title= (potentially also: |title-link=, |postscript=, |ref=, |type=)
['preface'] = {'preface'}, -- |contribution=
['registration'] = {'registration'}, -- |url-access= -- Used by InternetArchiveBot
['subscription'] = {'subscription'}, -- |url-access= -- Used by InternetArchiveBot
['unfit'] = {'unfit'}, -- |url-status= -- Used by InternetArchiveBot
['usurped'] = {'usurped'}, -- |url-status= -- Used by InternetArchiveBot
['vanc'] = {'vanc'}, -- |name-list-style=
['ymd'] = {'ymd'}, -- |df=
['ymd-all'] = {'ymd-all'}, -- |df=
-- ['yMd'] = {'yMd'}, -- |df=; not supported at en.wiki
-- ['yMd-all'] = {'yMd-all'}, -- |df=; not supported at en.wiki
}
--[[------------------------< X L A T E _ K E Y W O R D S >---------------------
this function builds a list, keywords_xlate{}, of the keywords found in keywords{} where the values from keywords{}
become the keys in keywords_xlate{} and the keys from keywords{} become the values in keywords_xlate{}:
['affirmative'] = {'yes', 'true', 'y'}, -- in keywords{}
becomes
['yes'] = 'affirmative', -- in keywords_xlate{}
['true'] = 'affirmative',
['y'] = 'affirmative',
the purpose of this function is to act as a translator between a non-English keyword and its English equivalent
that may be used in other modules of this suite
]]
local function xlate_keywords ()
local out_table = {}; -- output goes here
for k, keywords_t in pairs (keywords) do -- spin through the keywords table
for _, keyword in ipairs (keywords_t) do -- for each keyword
out_table[keyword] = k; -- create an entry in the output table where keyword is the key
end
end
return out_table;
end
local keywords_xlate = xlate_keywords (); -- the list of translated keywords
--[[----------------< M A K E _ K E Y W O R D S _ L I S T >---------------------
this function assembles, for parameter-value validation, the list of keywords appropriate to that parameter.
keywords_lists{}, is a table of tables from keywords{}
]]
local function make_keywords_list (keywords_lists)
local out_table = {}; -- output goes here
for _, keyword_list in ipairs (keywords_lists) do -- spin through keywords_lists{} and get a table of keywords
for _, keyword in ipairs (keyword_list) do -- spin through keyword_list{} and add each keyword, ...
table.insert (out_table, keyword); -- ... as plain text, to the output list
end
end
return out_table;
end
--[[----------------< K E Y W O R D S _ L I S T S >-----------------------------
this is a list of lists of valid keywords for the various parameters in [key].
Generally the keys in this table are the canonical en.wiki parameter names though
some are contrived because of use in multiple differently named parameters:
['yes_true_y'], ['id-access'].
The function make_keywords_list() extracts the individual keywords from the
appropriate list in keywords{}.
The lists in this table are used to validate the keyword assignment for the
parameters named in this table's keys.
]]
local keywords_lists = {
['yes_true_y'] = make_keywords_list ({keywords.affirmative}),
['contribution'] = make_keywords_list ({keywords.afterword, keywords.foreword, keywords.introduction, keywords.preface}),
['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all']}),
-- ['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all'], keywords.yMd, keywords['yMd-all']}), -- not supported at en.wiki
['mode'] = make_keywords_list ({keywords.cs1, keywords.cs2}),
['name-list-style'] = make_keywords_list ({keywords.amp, keywords['and'], keywords.vanc}),
['ref'] = make_keywords_list ({keywords.harv}), -- inverted check; |ref=harv no longer supported
['url-access'] = make_keywords_list ({keywords.subscription, keywords.limited, keywords.registration}),
['url-status'] = make_keywords_list ({keywords.dead, keywords.live, keywords.unfit, keywords.usurped, keywords['bot: unknown']}),
['id-access'] = make_keywords_list ({keywords.free}),
}
--[[---------------------< S T R I P M A R K E R S >----------------------------
Common pattern definition location for stripmarkers so that we don't have to go
hunting for them if (when) MediaWiki changes their form.
]]
local stripmarkers = {
['any'] = '\127[^\127]*UNIQ%-%-(%a+)%-[%a%d]+%-QINU[^\127]*\127', -- capture returns name of stripmarker
['math'] = '\127[^\127]*UNIQ%-%-math%-[%a%d]+%-QINU[^\127]*\127' -- math stripmarkers used in coins_cleanup() and coins_replace_math_stripmarker()
}
--[[------------< I N V I S I B L E _ C H A R A C T E R S >---------------------
This table holds non-printing or invisible characters indexed either by name or
by Unicode group. Values are decimal representations of UTF-8 codes. The table
is organized as a table of tables because the Lua pairs keyword returns table
data in an arbitrary order. Here, we want to process the table from top to bottom
because the entries at the top of the table are also found in the ranges specified
by the entries at the bottom of the table.
Also here is a pattern that recognizes stripmarkers that begin and end with the
delete characters. The nowiki stripmarker is not an error but some others are
because the parameter values that include them become part of the template's
metadata before stripmarker replacement.
]]
local invisible_defs = {
del = '\127', -- used to distinguish between stripmarker and del char
zwj = '\226\128\141', -- used with capture because zwj may be allowed
}
local invisible_chars = {
{'replacement', '\239\191\189'}, -- U+FFFD, EF BF BD
{'zero width joiner', '('.. invisible_defs.zwj .. ')'}, -- U+200D, E2 80 8D; capture because zwj may be allowed
{'zero width space', '\226\128\139'}, -- U+200B, E2 80 8B
{'hair space', '\226\128\138'}, -- U+200A, E2 80 8A
{'soft hyphen', '\194\173'}, -- U+00AD, C2 AD
{'horizontal tab', '\009'}, -- U+0009 (HT), 09
{'line feed', '\010'}, -- U+000A (LF), 0A
{'no-break space', '\194\160'}, -- U+00A0 (NBSP), C2 A0
{'carriage return', '\013'}, -- U+000D (CR), 0D
{'stripmarker', stripmarkers.any}, -- stripmarker; may or may not be an error; capture returns the stripmaker type
{'delete', '('.. invisible_defs.del .. ')'}, -- U+007F (DEL), 7F; must be done after stripmarker test; capture to distinguish isolated del chars not part of stripmarker
{'C0 control', '[\000-\008\011\012\014-\031]'}, -- U+0000–U+001F (NULL–US), 00–1F (except HT, LF, CR (09, 0A, 0D))
{'C1 control', '[\194\128-\194\159]'}, -- U+0080–U+009F (XXX–APC), C2 80 – C2 9F
-- {'Specials', '[\239\191\185-\239\191\191]'}, -- U+FFF9-U+FFFF, EF BF B9 – EF BF BF
-- {'Private use area', '[\238\128\128-\239\163\191]'}, -- U+E000–U+F8FF, EE 80 80 – EF A3 BF
-- {'Supplementary Private Use Area-A', '[\243\176\128\128-\243\191\191\189]'}, -- U+F0000–U+FFFFD, F3 B0 80 80 – F3 BF BF BD
-- {'Supplementary Private Use Area-B', '[\244\128\128\128-\244\143\191\189]'}, -- U+100000–U+10FFFD, F4 80 80 80 – F4 8F BF BD
}
--[[
Indic script makes use of zero width joiner as a character modifier so zwj
characters must be left in. This pattern covers all of the unicode characters
for these languages:
Devanagari 0900–097F – https://unicode.org/charts/PDF/U0900.pdf
Devanagari extended A8E0–A8FF – https://unicode.org/charts/PDF/UA8E0.pdf
Bengali 0980–09FF – https://unicode.org/charts/PDF/U0980.pdf
Gurmukhi 0A00–0A7F – https://unicode.org/charts/PDF/U0A00.pdf
Gujarati 0A80–0AFF – https://unicode.org/charts/PDF/U0A80.pdf
Oriya 0B00–0B7F – https://unicode.org/charts/PDF/U0B00.pdf
Tamil 0B80–0BFF – https://unicode.org/charts/PDF/U0B80.pdf
Telugu 0C00–0C7F – https://unicode.org/charts/PDF/U0C00.pdf
Kannada 0C80–0CFF – https://unicode.org/charts/PDF/U0C80.pdf
Malayalam 0D00–0D7F – https://unicode.org/charts/PDF/U0D00.pdf
plus the not-necessarily Indic scripts for Sinhala and Burmese:
Sinhala 0D80-0DFF - https://unicode.org/charts/PDF/U0D80.pdf
Myanmar 1000-109F - https://unicode.org/charts/PDF/U1000.pdf
Myanmar extended A AA60-AA7F - https://unicode.org/charts/PDF/UAA60.pdf
Myanmar extended B A9E0-A9FF - https://unicode.org/charts/PDF/UA9E0.pdf
the pattern is used by has_invisible_chars() and coins_cleanup()
]]
local indic_script = '[\224\164\128-\224\181\191\224\163\160-\224\183\191\225\128\128-\225\130\159\234\167\160-\234\167\191\234\169\160-\234\169\191]';
-- list of emoji that use zwj character (U+200D) to combine with another emoji
local emoji = { -- indexes are decimal forms of the hex values in U+xxxx
[127752] = true, -- U+1F308 🌈 rainbow
[127806] = true, -- U+1F33E 🌾 ear of rice
[127859] = true, -- U+1F373 🍳 cooking
[127891] = true, -- U+1F393 🎓 graduation cap
[127908] = true, -- U+1F3A4 🎤 microphone
[127912] = true, -- U+1F3A8 🎨 artist palette
[127979] = true, -- U+1F3EB 🏫 school
[127981] = true, -- U+1F3ED 🏭 factory
[128102] = true, -- U+1F466 👦 boy
[128103] = true, -- U+1F467 👧 girl
[128104] = true, -- U+1F468 👨 man
[128105] = true, -- U+1F469 👩 woman
[128139] = true, -- U+1F48B 💋 kiss mark
[128187] = true, -- U+1F4BB 💻 personal computer
[128188] = true, -- U+1F4BC 💼 brief case
[128295] = true, -- U+1F527 🔧 wrench
[128300] = true, -- U+1F52C 🔬 microscope
[128488] = true, -- U+1F5E8 🗨 left speech bubble
[128640] = true, -- U+1F680 🚀 rocket
[128658] = true, -- U+1F692 🚒 fire engine
[129309] = true, -- U+1F91D 🤝 handshake
[129455] = true, -- U+1F9AF 🦯 probing cane
[129456] = true, -- U+1F9B0 🦰 emoji component red hair
[129457] = true, -- U+1F9B1 🦱 emoji component curly hair
[129458] = true, -- U+1F9B2 🦲 emoji component bald
[129459] = true, -- U+1F9B3 🦳 emoji component white hair
[129466] = true, -- U+1F9BA 🦺 safety vest
[129468] = true, -- U+1F9BC 🦼 motorized wheelchair
[129469] = true, -- U+1F9BD 🦽 manual wheelchair
[129489] = true, -- U+1F9D1 🧑 adult
[9760] = true, -- U+2620 ☠ skull and crossbones
[9792] = true, -- U+2640 ♀ female sign
[9794] = true, -- U+2642 ♂ male sign
[9877] = true, -- U+2695 ⚕ staff of aesculapius
[9878] = true, -- U+2696 ⚖ scales
[9992] = true, -- U+2708 ✈ airplane
[10084] = true, -- U+2764 ❤ heavy black heart
}
--[[----------------------< L A N G U A G E S U P P O R T >-------------------
These tables and constants support various language-specific functionality.
]]
--local this_wiki_code = mw.getContentLanguage():getCode(); -- get this wiki's language code
local this_wiki_code = lang_obj:getCode(); -- get this wiki's language code
if string.match (mw.site.server, 'wikidata') then
this_wiki_code = mw.getCurrentFrame():preprocess('{{int:lang}}'); -- on Wikidata so use interface language setting instead
end
local mw_languages_by_tag_t = mw.language.fetchLanguageNames (this_wiki_code, 'all'); -- get a table of language tag/name pairs known to Wikimedia; used for interwiki tests
local mw_languages_by_name_t = {};
for k, v in pairs (mw_languages_by_tag_t) do -- build a 'reversed' table name/tag language pairs know to MediaWiki; used for |language=
v = mw.ustring.lower (v); -- lowercase for tag fetch; get name's proper case from mw_languages_by_tag_t[<tag>]
if mw_languages_by_name_t[v] then -- when name already in the table
if 2 == #k or 3 == #k then -- if tag does not have subtags
mw_languages_by_name_t[v] = k; -- prefer the shortest tag for this name
end
else -- here when name not in the table
mw_languages_by_name_t[v] = k; -- so add name and matching tag
end
end
local inter_wiki_map = {}; -- map of interwiki prefixes that are language-code prefixes
for k, v in pairs (mw.site.interwikiMap ('local')) do -- spin through the base interwiki map (limited to local)
if mw_languages_by_tag_t[v["prefix"]] then -- if the prefix matches a known language tag
inter_wiki_map[v["prefix"]] = true; -- add it to our local map
end
end
--[[--------------------< S C R I P T _ L A N G _ C O D E S >-------------------
This table is used to hold ISO 639-1 two-character and ISO 639-3 three-character
language codes that apply only to |script-title= and |script-chapter=
]]
local script_lang_codes = {
'ab', 'am', 'ar', 'be', 'bg', 'bn', 'bo', 'bs', 'dv', 'dz', 'el', 'fa', 'gu',
'he', 'hi', 'hy', 'ja', 'ka', 'kk', 'km', 'kn', 'ko', 'ku', 'ky', 'lo', 'mk',
'ml', 'mn', 'mr', 'my', 'ne', 'or', 'ota', 'ps', 'ru', 'sd', 'si', 'sr', 'syc',
'ta', 'te', 'tg', 'th', 'ti', 'ug', 'uk', 'ur', 'uz', 'yi', 'yue', 'zh'
};
--[[---------------< L A N G U A G E R E M A P P I N G >----------------------
These tables hold language information that is different (correct) from MediaWiki's definitions
For each ['code'] = 'language name' in lang_code_remap{} there must be a matching ['language name'] = {'language name', 'code'} in lang_name_remap{}
lang_code_remap{}:
key is always lowercase ISO 639-1, -2, -3 language code or a valid lowercase IETF language tag
value is properly spelled and capitalized language name associated with key
only one language name per key;
key/value pair must have matching entry in lang_name_remap{}
lang_name_remap{}:
key is always lowercase language name
value is a table the holds correctly spelled and capitalized language name [1] and associated code [2] (code must match a code key in lang_code_remap{})
may have multiple keys referring to a common preferred name and code; For example:
['kolsch'] and ['kölsch'] both refer to 'Kölsch' and 'ksh'
]]
local lang_code_remap = { -- used for |language= and |script-title= / |script-chapter=
['als'] = 'Tosk Albanian', -- MediaWiki returns Alemannisch
['bh'] = 'Bihari', -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bla'] = 'Blackfoot', -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['bn'] = 'Bengali', -- MediaWiki returns Bangla
['ca-valencia'] = 'Valencian', -- IETF variant of Catalan
['ilo'] = 'Ilocano', -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['ksh'] = 'Kölsch', -- MediaWiki: Colognian; use IANA/ISO 639 preferred name
['ksh-x-colog'] = 'Colognian', -- override MediaWiki ksh; no IANA/ISO 639 code for Colognian; IETF private code created at Module:Lang/data
['mis-x-ripuar'] = 'Ripuarian', -- override MediaWiki ksh; no IANA/ISO 639 code for Ripuarian; IETF private code created at Module:Lang/data
['nan-tw'] = 'Taiwanese Hokkien', -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese and support en.wiki preferred name
}
local lang_name_remap = { -- used for |language=; names require proper capitalization; tags must be lowercase
['alemannisch'] = {'Swiss German', 'gsw'}, -- not an ISO or IANA language name; MediaWiki uses 'als' as a subdomain name for Alemannic Wikipedia: als.wikipedia.org
['bangla'] = {'Bengali', 'bn'}, -- MediaWiki returns Bangla (the endonym) but we want Bengali (the exonym); here we remap
['bengali'] = {'Bengali', 'bn'}, -- MediaWiki doesn't use exonym so here we provide correct language name and 639-1 code
['bhojpuri'] = {'Bhojpuri', 'bho'}, -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bihari'] = {'Bihari', 'bh'}, -- MediaWiki replaces 'Bihari' with 'Bhojpuri' so 'Bihari' cannot be found
['blackfoot'] = {'Blackfoot', 'bla'}, -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['colognian'] = {'Colognian', 'ksh-x-colog'}, -- MediaWiki preferred name for ksh
['ilocano'] = {'Ilocano', 'ilo'}, -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['kolsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name (use non-diacritical o instead of umlaut ö)
['kölsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name
['ripuarian'] = {'Ripuarian', 'mis-x-ripuar'}, -- group of dialects; no code in MediaWiki or in IANA/ISO 639
['taiwanese hokkien'] = {'Taiwanese Hokkien', 'nan-tw'}, -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese
['tosk albanian'] = {'Tosk Albanian', 'als'}, -- MediaWiki replaces 'Tosk Albanian' with 'Alemannisch' so 'Tosk Albanian' cannot be found
['valencian'] = {'Valencian', 'ca'}, -- variant of Catalan; categorizes as Catalan
}
--[[---------------< P R O P E R T I E S _ C A T E G O R I E S >----------------
Properties categories. These are used for investigating qualities of citations.
]]
local prop_cats = {
['foreign-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is foreign-language name, $2 is ISO639-1 code
['foreign-lang-source-2'] = 'CS1 foreign language sources (ISO 639-2)|$1', -- |language= category; a cat for ISO639-2 languages; $1 is the ISO 639-2 code used as a sort key
['jul-greg-uncertainty'] = 'CS1: Julian–Gregorian uncertainty', -- probably temporary cat to identify scope of template with dates 1 October 1582 – 1 January 1926
['local-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is local-language name, $2 is ISO639-1 code; not emitted when local_lang_cat_enable is false
['location-test'] = 'CS1 location test',
['long-vol'] = 'CS1: long volume value', -- probably temporary cat to identify scope of |volume= values longer than 4 charachters
['script'] = 'CS1 uses $1-language script ($2)', -- |script-title=xx: has matching category; $1 is language name, $2 is ISO639-1 code
['tracked-param'] = 'CS1 tracked parameter: $1', -- $1 is base (enumerators removed) parameter name
['year-range-abbreviated'] = 'CS1: abbreviated year range', -- probably temporary cat to identify scope of |date=, |year= values using YYYY–YY form
}
--[[-------------------< T I T L E _ T Y P E S >--------------------------------
Here we map a template's CitationClass to TitleType (default values for |type= parameter)
]]
local title_types = {
['AV-media-notes'] = 'Media notes',
['interview'] = 'Interview',
['mailinglist'] = 'Mailing list',
['map'] = 'Map',
['podcast'] = 'Podcast',
['pressrelease'] = 'Press release',
['report'] = 'Report',
['speech'] = 'Speech',
['techreport'] = 'Technical report',
['thesis'] = 'Thesis',
}
--[[===================<< E R R O R M E S S A G I N G >>======================
]]
--[[----------< E R R O R M E S S A G E S U P P L I M E N T S >-------------
I18N for those messages that are supplemented with additional specific text that
describes the reason for the error
TODO: merge this with special_case_translations{}?
]]
local err_msg_supl = {
['char'] = 'invalid character', -- |isbn=, |sbn=
['check'] = 'checksum', -- |isbn=, |sbn=
['flag'] = 'flag', -- |archive-url=
['form'] = 'invalid form', -- |isbn=, |sbn=
['group'] = 'invalid group id', -- |isbn=
['initials'] = 'initials', -- Vancouver
['invalid language code'] = 'invalid language code', -- |script-<param>=
['journal'] = 'journal', -- |bibcode=
['length'] = 'length', -- |isbn=, |bibcode=, |sbn=
['liveweb'] = 'liveweb', -- |archive-url=
['missing comma'] = 'missing comma', -- Vancouver
['missing prefix'] = 'missing prefix', -- |script-<param>=
['missing title part'] = 'missing title part', -- |script-<param>=
['name'] = 'name', -- Vancouver
['non-Latin char'] = 'non-Latin character', -- Vancouver
['path'] = 'path', -- |archive-url=
['prefix'] = 'invalid prefix', -- |isbn=
['punctuation'] = 'punctuation', -- Vancouver
['save'] = 'save command', -- |archive-url=
['suffix'] = 'suffix', -- Vancouver
['timestamp'] = 'timestamp', -- |archive-url=
['unknown language code'] = 'unknown language code', -- |script-<param>=
['value'] = 'value', -- |bibcode=
['year'] = 'year', -- |bibcode=
}
--[[--------------< E R R O R _ C O N D I T I O N S >---------------------------
Error condition table. This table has two sections: errors at the top, maintenance
at the bottom. Maint 'messaging' does not have a 'message' (message=nil)
The following contains a list of IDs for various error conditions defined in the
code. For each ID, we specify a text message to display, an error category to
include, and whether the error message should be wrapped as a hidden comment.
Anchor changes require identical changes to matching anchor in Help:CS1 errors
TODO: rename error_conditions{} to something more generic; create separate error
and maint tables inside that?
]]
local error_conditions = {
err_accessdate_missing_url = {
message = '<code class="cs1-code">|access-date=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'accessdate_missing_url',
category = 'CS1 errors: access-date without URL',
hidden = false
},
err_apostrophe_markup = {
message = 'Italic or bold markup not allowed in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'apostrophe_markup',
category = 'CS1 errors: markup',
hidden = false
},
err_archive_missing_date = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|archive-date=</code>',
anchor = 'archive_missing_date',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_url = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'archive_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_url = {
message = '<code class="cs1-code">|archive-url=</code> is malformed: $1', -- $1 is error message detail
anchor = 'archive_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_arxiv_missing = {
message = '<code class="cs1-code">|arxiv=</code> required',
anchor = 'arxiv_missing',
category = 'CS1 errors: arXiv', -- same as bad arxiv
hidden = false
},
err_asintld_missing_asin = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|asin=</code>', -- $1 is parameter name
anchor = 'asintld_missing_asin',
category = 'CS1 errors: ASIN TLD',
hidden = false
},
err_bad_arxiv = {
message = 'Check <code class="cs1-code">|arxiv=</code> value',
anchor = 'bad_arxiv',
category = 'CS1 errors: arXiv',
hidden = false
},
err_bad_asin = {
message = 'Check <code class="cs1-code">|asin=</code> value',
anchor = 'bad_asin',
category ='CS1 errors: ASIN',
hidden = false
},
err_bad_asin_tld = {
message = 'Check <code class="cs1-code">|asin-tld=</code> value',
anchor = 'bad_asin_tld',
category ='CS1 errors: ASIN TLD',
hidden = false
},
err_bad_bibcode = {
message = 'Check <code class="cs1-code">|bibcode=</code> $1', -- $1 is error message detail
anchor = 'bad_bibcode',
category = 'CS1 errors: bibcode',
hidden = false
},
err_bad_biorxiv = {
message = 'Check <code class="cs1-code">|biorxiv=</code> value',
anchor = 'bad_biorxiv',
category = 'CS1 errors: bioRxiv',
hidden = false
},
err_bad_citeseerx = {
message = 'Check <code class="cs1-code">|citeseerx=</code> value',
anchor = 'bad_citeseerx',
category = 'CS1 errors: citeseerx',
hidden = false
},
err_bad_date = {
message = 'Check date values in: $1', -- $1 is a parameter name list
anchor = 'bad_date',
category = 'CS1 errors: dates',
hidden = false
},
err_bad_doi = {
message = 'Check <code class="cs1-code">|doi=</code> value',
anchor = 'bad_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_bad_hdl = {
message = 'Check <code class="cs1-code">|hdl=</code> value',
anchor = 'bad_hdl',
category = 'CS1 errors: HDL',
hidden = false
},
err_bad_isbn = {
message = 'Check <code class="cs1-code">|isbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_isbn',
category = 'CS1 errors: ISBN',
hidden = false
},
err_bad_ismn = {
message = 'Check <code class="cs1-code">|ismn=</code> value',
anchor = 'bad_ismn',
category = 'CS1 errors: ISMN',
hidden = false
},
err_bad_issn = {
message = 'Check <code class="cs1-code">|$1issn=</code> value', -- $1 is 'e' or '' for eissn or issn
anchor = 'bad_issn',
category = 'CS1 errors: ISSN',
hidden = false
},
err_bad_jfm = {
message = 'Check <code class="cs1-code">|jfm=</code> value',
anchor = 'bad_jfm',
category = 'CS1 errors: JFM',
hidden = false
},
err_bad_jstor = {
message = 'Check <code class="cs1-code">|jstor=</code> value',
anchor = 'bad_jstor',
category = 'CS1 errors: JSTOR',
hidden = false
},
err_bad_lccn = {
message = 'Check <code class="cs1-code">|lccn=</code> value',
anchor = 'bad_lccn',
category = 'CS1 errors: LCCN',
hidden = false
},
err_bad_mr = {
message = 'Check <code class="cs1-code">|mr=</code> value',
anchor = 'bad_mr',
category = 'CS1 errors: MR',
hidden = false
},
err_bad_oclc = {
message = 'Check <code class="cs1-code">|oclc=</code> value',
anchor = 'bad_oclc',
category = 'CS1 errors: OCLC',
hidden = false
},
err_bad_ol = {
message = 'Check <code class="cs1-code">|ol=</code> value',
anchor = 'bad_ol',
category = 'CS1 errors: OL',
hidden = false
},
err_bad_osti = {
message = 'Check <code class="cs1-code">|osti=</code> value',
anchor = 'bad_osti',
category = 'CS1 errors: OSTI',
hidden = false
},
err_bad_paramlink = { -- for |title-link=, |author/editor/translator-link=, |series-link=, |episode-link=
message = 'Check <code class="cs1-code">|$1=</code> value', -- $1 is parameter name
anchor = 'bad_paramlink',
category = 'CS1 errors: parameter link',
hidden = false
},
err_bad_pmc = {
message = 'Check <code class="cs1-code">|pmc=</code> value',
anchor = 'bad_pmc',
category = 'CS1 errors: PMC',
hidden = false
},
err_bad_pmid = {
message = 'Check <code class="cs1-code">|pmid=</code> value',
anchor = 'bad_pmid',
category = 'CS1 errors: PMID',
hidden = false
},
err_bad_rfc = {
message = 'Check <code class="cs1-code">|rfc=</code> value',
anchor = 'bad_rfc',
category = 'CS1 errors: RFC',
hidden = false
},
err_bad_s2cid = {
message = 'Check <code class="cs1-code">|s2cid=</code> value',
anchor = 'bad_s2cid',
category = 'CS1 errors: S2CID',
hidden = false
},
err_bad_sbn = {
message = 'Check <code class="cs1-code">|sbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_sbn',
category = 'CS1 errors: SBN',
hidden = false
},
err_bad_ssrn = {
message = 'Check <code class="cs1-code">|ssrn=</code> value',
anchor = 'bad_ssrn',
category = 'CS1 errors: SSRN',
hidden = false
},
err_bad_url = {
message = 'Check $1 value', -- $1 is parameter name
anchor = 'bad_url',
category = 'CS1 errors: URL',
hidden = false
},
err_bad_usenet_id = {
message = 'Check <code class="cs1-code">|message-id=</code> value',
anchor = 'bad_message_id',
category = 'CS1 errors: message-id',
hidden = false
},
err_bad_zbl = {
message = 'Check <code class="cs1-code">|zbl=</code> value',
anchor = 'bad_zbl',
category = 'CS1 errors: Zbl',
hidden = false
},
err_bare_url_missing_title = {
message = '$1 missing title', -- $1 is parameter name
anchor = 'bare_url_missing_title',
category = 'CS1 errors: bare URL',
hidden = false
},
err_biorxiv_missing = {
message = '<code class="cs1-code">|biorxiv=</code> required',
anchor = 'biorxiv_missing',
category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv
hidden = false
},
err_chapter_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'chapter_ignored',
category = 'CS1 errors: chapter ignored',
hidden = false
},
err_citation_missing_title = {
message = 'Missing or empty <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'citation_missing_title',
category = 'CS1 errors: missing title',
hidden = false
},
err_citeseerx_missing = {
message = '<code class="cs1-code">|citeseerx=</code> required',
anchor = 'citeseerx_missing',
category = 'CS1 errors: citeseerx', -- same as bad citeseerx
hidden = false
},
err_cite_web_url = { -- this error applies to cite web and to cite podcast
message = 'Missing or empty <code class="cs1-code">|url=</code>',
anchor = 'cite_web_url',
category = 'CS1 errors: requires URL',
hidden = false
},
err_class_ignored = {
message = '<code class="cs1-code">|class=</code> ignored',
anchor = 'class_ignored',
category = 'CS1 errors: class',
hidden = false
},
err_contributor_ignored = {
message = '<code class="cs1-code">|contributor=</code> ignored',
anchor = 'contributor_ignored',
category = 'CS1 errors: contributor',
hidden = false
},
err_contributor_missing_required_param = {
message = '<code class="cs1-code">|contributor=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'contributor_missing_required_param',
category = 'CS1 errors: contributor',
hidden = false
},
err_deprecated_params = {
message = 'Cite uses deprecated parameter <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'deprecated_params',
category = 'CS1 errors: deprecated parameters',
hidden = false
},
err_disp_name = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name; $2 is the assigned value
anchor = 'disp_name',
category = 'CS1 errors: display-names',
hidden = false,
},
err_doibroken_missing_doi = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|doi=</code>', -- $1 is parameter name
anchor = 'doibroken_missing_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_embargo_missing_pmc = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|pmc=</code>', -- $1 is parameter name
anchor = 'embargo_missing_pmc',
category = 'CS1 errors: PMC embargo',
hidden = false
},
err_empty_citation = {
message = 'Empty citation',
anchor = 'empty_citation',
category = 'CS1 errors: empty citation',
hidden = false
},
err_etal = {
message = 'Explicit use of et al. in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'explicit_et_al',
category = 'CS1 errors: explicit use of et al.',
hidden = false
},
err_extra_text_edition = {
message = '<code class="cs1-code">|edition=</code> has extra text',
anchor = 'extra_text_edition',
category = 'CS1 errors: extra text: edition',
hidden = false,
},
err_extra_text_issue = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_issue',
category = 'CS1 errors: extra text: issue',
hidden = false,
},
err_extra_text_pages = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_pages',
category = 'CS1 errors: extra text: pages',
hidden = false,
},
err_extra_text_volume = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_volume',
category = 'CS1 errors: extra text: volume',
hidden = true,
},
err_first_missing_last = {
message = '<code class="cs1-code">|$1=</code> missing <code class="cs1-code">|$2=</code>', -- $1 is first alias, $2 is matching last alias
anchor = 'first_missing_last',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_format_missing_url = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|$2=</code>', -- $1 is format parameter $2 is url parameter
anchor = 'format_missing_url',
category = 'CS1 errors: format without URL',
hidden = false
},
err_generic_name = {
message = '<code class="cs1-code">|$1=</code> has generic name', -- $1 is parameter name
anchor = 'generic_name',
category = 'CS1 errors: generic name',
hidden = false,
},
err_generic_title = {
message = 'Cite uses generic title',
anchor = 'generic_title',
category = 'CS1 errors: generic title',
hidden = false,
},
err_invalid_param_val = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name $2 is parameter value
anchor = 'invalid_param_val',
category = 'CS1 errors: invalid parameter value',
hidden = false
},
err_invisible_char = {
message = '$1 in $2 at position $3', -- $1 is invisible char $2 is parameter name $3 is position number
anchor = 'invisible_char',
category = 'CS1 errors: invisible characters',
hidden = false
},
err_missing_name = {
message = 'Missing <code class="cs1-code">|$1$2=</code>', -- $1 is modified NameList; $2 is enumerator
anchor = 'missing_name',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_missing_periodical = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical periodical parameter name for cite $1
anchor = 'missing_periodical',
category = 'CS1 errors: missing periodical',
hidden = true
},
err_missing_pipe = {
message = 'Missing pipe in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'missing_pipe',
category = 'CS1 errors: missing pipe',
hidden = false
},
err_param_access_requires_param = {
message = '<code class="cs1-code">|$1-access=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'param_access_requires_param',
category = 'CS1 errors: param-access',
hidden = false
},
err_param_has_ext_link = {
message = 'External link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_ext_link',
category = 'CS1 errors: external links',
hidden = false
},
err_parameter_ignored = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'parameter_ignored',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_parameter_ignored_suggest = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored (<code class="cs1-code">|$2=</code> suggested)', -- $1 is unknown parameter $2 is suggested parameter name
anchor = 'parameter_ignored_suggest',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_redundant_parameters = {
message = 'More than one of $1 specified', -- $1 is error message detail
anchor = 'redundant_parameters',
category = 'CS1 errors: redundant parameter',
hidden = false
},
err_script_parameter = {
message = 'Invalid <code class="cs1-code">|$1=</code>: $2', -- $1 is parameter name $2 is script language code or error detail
anchor = 'script_parameter',
category = 'CS1 errors: script parameters',
hidden = false
},
err_ssrn_missing = {
message = '<code class="cs1-code">|ssrn=</code> required',
anchor = 'ssrn_missing',
category = 'CS1 errors: SSRN', -- same as bad arxiv
hidden = false
},
err_text_ignored = {
message = 'Text "$1" ignored', -- $1 is ignored text
anchor = 'text_ignored',
category = 'CS1 errors: unrecognized parameter',
hidden = false
},
err_trans_missing_title = {
message = '<code class="cs1-code">|trans-$1=</code> requires <code class="cs1-code">|$1=</code> or <code class="cs1-code">|script-$1=</code>', -- $1 is base parameter name
anchor = 'trans_missing_title',
category = 'CS1 errors: translated title',
hidden = false
},
err_param_unknown_empty = {
message = 'Cite has empty unknown parameter$1: $2', -- $1 is 's' or empty space; $2 is emty unknown param list
anchor = 'param_unknown_empty',
category = 'CS1 errors: empty unknown parameters',
hidden = false
},
err_vancouver = {
message = 'Vancouver style error: $1 in name $2', -- $1 is error detail, $2 is the nth name
anchor = 'vancouver',
category = 'CS1 errors: Vancouver style',
hidden = false
},
err_wikilink_in_url = {
message = 'URL–wikilink conflict', -- uses ndash
anchor = 'wikilink_in_url',
category = 'CS1 errors: URL–wikilink conflict', -- uses ndash
hidden = false
},
--[[--------------------------< M A I N T >-------------------------------------
maint messages do not have a message (message = nil); otherwise the structure
is the same as error messages
]]
maint_archived_copy = {
message = nil,
anchor = 'archived_copy',
category = 'CS1 maint: archived copy as title',
hidden = true,
},
maint_authors = {
message = nil,
anchor = 'authors',
category = 'CS1 maint: uses authors parameter',
hidden = true,
},
maint_bot_unknown = {
message = nil,
anchor = 'bot:_unknown',
category = 'CS1 maint: bot: original URL status unknown',
hidden = true,
},
maint_date_auto_xlated = { -- date auto-translation not supported by en.wiki
message = nil,
anchor = 'date_auto_xlated',
category = 'CS1 maint: date auto-translated',
hidden = true,
},
maint_date_format = {
message = nil,
anchor = 'date_format',
category = 'CS1 maint: date format',
hidden = true,
},
maint_date_year = {
message = nil,
anchor = 'date_year',
category = 'CS1 maint: date and year',
hidden = true,
},
maint_doi_ignore = {
message = nil,
anchor = 'doi_ignore',
category = 'CS1 maint: ignored DOI errors',
hidden = true,
},
maint_doi_inactive = {
message = nil,
anchor = 'doi_inactive',
category = 'CS1 maint: DOI inactive',
hidden = true,
},
maint_doi_inactive_dated = {
message = nil,
anchor = 'doi_inactive_dated',
category = 'CS1 maint: DOI inactive as of $2$3$1', -- $1 is year, $2 is month-name or empty string, $3 is space or empty string
hidden = true,
},
maint_extra_punct = {
message = nil,
anchor = 'extra_punct',
category = 'CS1 maint: extra punctuation',
hidden = true,
},
maint_isbn_ignore = {
message = nil,
anchor = 'ignore_isbn_err',
category = 'CS1 maint: ignored ISBN errors',
hidden = true,
},
maint_issn_ignore = {
message = nil,
anchor = 'ignore_issn',
category = 'CS1 maint: ignored ISSN errors',
hidden = true,
},
maint_jfm_format = {
message = nil,
anchor = 'jfm_format',
category = 'CS1 maint: JFM format',
hidden = true,
},
maint_location = {
message = nil,
anchor = 'location',
category = 'CS1 maint: location',
hidden = true,
},
maint_mr_format = {
message = nil,
anchor = 'mr_format',
category = 'CS1 maint: MR format',
hidden = true,
},
maint_mult_names = {
message = nil,
anchor = 'mult_names',
category = 'CS1 maint: multiple names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_numeric_names = {
message = nil,
anchor = 'numeric_names',
category = 'CS1 maint: numeric names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_others = {
message = nil,
anchor = 'others',
category = 'CS1 maint: others',
hidden = true,
},
maint_others_avm = {
message = nil,
anchor = 'others_avm',
category = 'CS1 maint: others in cite AV media (notes)',
hidden = true,
},
maint_pmc_embargo = {
message = nil,
anchor = 'embargo',
category = 'CS1 maint: PMC embargo expired',
hidden = true,
},
maint_pmc_format = {
message = nil,
anchor = 'pmc_format',
category = 'CS1 maint: PMC format',
hidden = true,
},
maint_postscript = {
message = nil,
anchor = 'postscript',
category = 'CS1 maint: postscript',
hidden = true,
},
maint_ref_duplicates_default = {
message = nil,
anchor = 'ref_default',
category = 'CS1 maint: ref duplicates default',
hidden = true,
},
maint_unfit = {
message = nil,
anchor = 'unfit',
category = 'CS1 maint: unfit URL',
hidden = true,
},
maint_unknown_lang = {
message = nil,
anchor = 'unknown_lang',
category = 'CS1 maint: unrecognized language',
hidden = true,
},
maint_untitled = {
message = nil,
anchor = 'untitled',
category = 'CS1 maint: untitled periodical',
hidden = true,
},
maint_url_status = {
message = nil,
anchor = 'url_status',
category = 'CS1 maint: url-status',
hidden = true,
},
maint_zbl = {
message = nil,
anchor = 'zbl',
category = 'CS1 maint: Zbl',
hidden = true,
},
}
--[[--------------------------< I D _ H A N D L E R S >--------------------------------------------------------
The following contains a list of values for various defined identifiers. For each
identifier we specify a variety of information necessary to properly render the
identifier in the citation.
parameters: a list of parameter aliases for this identifier; first in the list is the canonical form
link: Wikipedia article name
redirect: a local redirect to a local Wikipedia article name; at en.wiki, 'ISBN (identifier)' is a redirect to 'International Standard Book Number'
q: Wikidata q number for the identifier
label: the label preceeding the identifier; label is linked to a Wikipedia article (in this order):
redirect from id_handlers['<id>'].redirect when use_identifier_redirects is true
Wikidata-supplied article name for the local wiki from id_handlers['<id>'].q
local article name from id_handlers['<id>'].link
prefix: the first part of a URL that will be concatenated with a second part which usually contains the identifier
suffix: optional third part to be added after the identifier
encode: true if URI should be percent-encoded; otherwise false
COinS: identifier link or keyword for use in COinS:
for identifiers registered at info-uri.info use: info:.... where '...' is the appropriate identifier label
for identifiers that have COinS keywords, use the keyword: rft.isbn, rft.issn, rft.eissn
for |asin= and |ol=, which require assembly, use the keyword: url
for others make a URL using the value in prefix/suffix and #label, use the keyword: pre (not checked; any text other than 'info', 'rft', or 'url' works here)
set to nil to leave the identifier out of the COinS
separator: character or text between label and the identifier in the rendered citation
id_limit: for those identifiers with established limits, this property holds the upper limit
access: use this parameter to set the access level for all instances of this identifier.
the value must be a valid access level for an identifier (see ['id-access'] in this file).
custom_access: to enable custom access level for an identifier, set this parameter
to the parameter that should control it (normally 'id-access')
]]
local id_handlers = {
['ARXIV'] = {
parameters = {'arxiv', 'eprint'},
link = 'arXiv',
redirect = 'arXiv (identifier)',
q = 'Q118398',
label = 'arXiv',
prefix = '//arxiv.org/abs/', -- protocol-relative tested 2013-09-04
encode = false,
COinS = 'info:arxiv',
separator = ':',
access = 'free', -- free to read
},
['ASIN'] = {
parameters = { 'asin', 'ASIN' },
link = 'Amazon Standard Identification Number',
redirect = 'ASIN (identifier)',
q = 'Q1753278',
label = 'ASIN',
prefix = '//www.amazon.',
COinS = 'url',
separator = ' ',
encode = false;
},
['BIBCODE'] = {
parameters = {'bibcode'},
link = 'Bibcode',
redirect = 'Bibcode (identifier)',
q = 'Q25754',
label = 'Bibcode',
prefix = 'https://ui.adsabs.harvard.edu/abs/',
encode = false,
COinS = 'info:bibcode',
separator = ':',
custom_access = 'bibcode-access',
},
['BIORXIV'] = {
parameters = {'biorxiv'},
link = 'bioRxiv',
redirect = 'bioRxiv (identifier)',
q = 'Q19835482',
label = 'bioRxiv',
prefix = '//doi.org/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['CITESEERX'] = {
parameters = {'citeseerx'},
link = 'CiteSeerX',
redirect = 'CiteSeerX (identifier)',
q = 'Q2715061',
label = 'CiteSeerX',
prefix = '//citeseerx.ist.psu.edu/viewdoc/summary?doi=',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['DOI'] = { -- Used by InternetArchiveBot
parameters = { 'doi', 'DOI'},
link = 'Digital object identifier',
redirect = 'doi (identifier)',
q = 'Q25670',
label = 'doi',
prefix = '//doi.org/',
COinS = 'info:doi',
separator = ':',
encode = true,
custom_access = 'doi-access',
},
['EISSN'] = {
parameters = {'eissn', 'EISSN'},
link = 'International Standard Serial Number#Electronic ISSN',
redirect = 'eISSN (identifier)',
q = 'Q46339674',
label = 'eISSN',
prefix = '//www.worldcat.org/issn/',
COinS = 'rft.eissn',
encode = false,
separator = ' ',
},
['HDL'] = {
parameters = { 'hdl', 'HDL' },
link = 'Handle System',
redirect = 'hdl (identifier)',
q = 'Q3126718',
label = 'hdl',
prefix = '//hdl.handle.net/',
COinS = 'info:hdl',
separator = ':',
encode = true,
custom_access = 'hdl-access',
},
['ISBN'] = { -- Used by InternetArchiveBot
parameters = {'isbn', 'ISBN'},
link = 'International Standard Book Number',
redirect = 'ISBN (identifier)',
q = 'Q33057',
label = 'ISBN',
prefix = 'Special:BookSources/',
COinS = 'rft.isbn',
separator = ' ',
},
['ISMN'] = {
parameters = {'ismn', 'ISMN'},
link = 'International Standard Music Number',
redirect = 'ISMN (identifier)',
q = 'Q1666938',
label = 'ISMN',
prefix = '', -- not currently used;
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['ISSN'] = {
parameters = {'issn', 'ISSN'},
link = 'International Standard Serial Number',
redirect = 'ISSN (identifier)',
q = 'Q131276',
label = 'ISSN',
prefix = '//www.worldcat.org/issn/',
COinS = 'rft.issn',
encode = false,
separator = ' ',
},
['JFM'] = {
parameters = {'jfm', 'JFM'},
link = 'Jahrbuch über die Fortschritte der Mathematik',
redirect = 'JFM (identifier)',
q = '',
label = 'JFM',
prefix = '//zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['JSTOR'] = {
parameters = {'jstor', 'JSTOR'},
link = 'JSTOR',
redirect = 'JSTOR (identifier)',
q = 'Q1420342',
label = 'JSTOR',
prefix = '//www.jstor.org/stable/', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
custom_access = 'jstor-access',
},
['LCCN'] = {
parameters = {'lccn', 'LCCN'},
link = 'Library of Congress Control Number',
redirect = 'LCCN (identifier)',
q = 'Q620946',
label = 'LCCN',
prefix = '//lccn.loc.gov/', -- protocol-relative tested 2015-12-28
COinS = 'info:lccn',
encode = false,
separator = ' ',
},
['MR'] = {
parameters = {'mr', 'MR'},
link = 'Mathematical Reviews',
redirect = 'MR (identifier)',
q = 'Q211172',
label = 'MR',
prefix = '//www.ams.org/mathscinet-getitem?mr=', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['OCLC'] = {
parameters = {'oclc', 'OCLC'},
link = 'OCLC',
redirect = 'OCLC (identifier)',
q = 'Q190593',
label = 'OCLC',
prefix = '//www.worldcat.org/oclc/',
COinS = 'info:oclcnum',
encode = true,
separator = ' ',
id_limit = 9999999999, -- 10-digits
},
['OL'] = {
parameters = { 'ol', 'OL' },
link = 'Open Library',
redirect = 'OL (identifier)',
q = 'Q1201876',
label = 'OL',
prefix = '//openlibrary.org/',
COinS = 'url',
separator = ' ',
encode = true,
custom_access = 'ol-access',
},
['OSTI'] = {
parameters = {'osti', 'OSTI'},
link = 'Office of Scientific and Technical Information',
redirect = 'OSTI (identifier)',
q = 'Q2015776',
label = 'OSTI',
prefix = '//www.osti.gov/biblio/', -- protocol-relative tested 2018-09-12
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 23010000,
custom_access = 'osti-access',
},
['PMC'] = {
parameters = {'pmc', 'PMC'},
link = 'PubMed Central',
redirect = 'PMC (identifier)',
q = 'Q229883',
label = 'PMC',
prefix = '//www.ncbi.nlm.nih.gov/pmc/articles/PMC',
suffix = '',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 9500000,
access = 'free', -- free to read
},
['PMID'] = {
parameters = {'pmid', 'PMID'},
link = 'PubMed Identifier',
redirect = 'PMID (identifier)',
q = 'Q2082879',
label = 'PMID',
prefix = '//pubmed.ncbi.nlm.nih.gov/',
COinS = 'info:pmid',
encode = false,
separator = ' ',
id_limit = 36400000,
},
['RFC'] = {
parameters = {'rfc', 'RFC'},
link = 'Request for Comments',
redirect = 'RFC (identifier)',
q = 'Q212971',
label = 'RFC',
prefix = '//tools.ietf.org/html/rfc',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = 9300,
access = 'free', -- free to read
},
['SBN'] = {
parameters = {'sbn', 'SBN'},
link = 'Standard Book Number', -- redirect to International_Standard_Book_Number#History
redirect = 'SBN (identifier)',
label = 'SBN',
prefix = 'Special:BookSources/0-', -- prefix has leading zero necessary to make 9-digit sbn a 10-digit isbn
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['SSRN'] = {
parameters = {'ssrn', 'SSRN'},
link = 'Social Science Research Network',
redirect = 'SSRN (identifier)',
q = 'Q7550801',
label = 'SSRN',
prefix = '//ssrn.com/abstract=', -- protocol-relative tested 2013-09-04
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = 4200000,
custom_access = 'ssrn-access',
},
['S2CID'] = {
parameters = {'s2cid', 'S2CID'},
link = 'Semantic Scholar',
redirect = 'S2CID (identifier)',
q = 'Q22908627',
label = 'S2CID',
prefix = 'https://api.semanticscholar.org/CorpusID:',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = 254000000,
custom_access = 's2cid-access',
},
['USENETID'] = {
parameters = {'message-id'},
link = 'Usenet',
redirect = 'Usenet (identifier)',
q = 'Q193162',
label = 'Usenet:',
prefix = 'news:',
encode = false,
COinS = 'pre', -- use prefix value
separator = ' ',
},
['ZBL'] = {
parameters = {'zbl', 'ZBL' },
link = 'Zentralblatt MATH',
redirect = 'Zbl (identifier)',
q = 'Q190269',
label = 'Zbl',
prefix = '//zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
}
--[[--------------------------< E X P O R T S >---------------------------------
]]
return {
use_identifier_redirects = true, -- when true use redirect name for identifier label links; always true at en.wiki
local_lang_cat_enable = false; -- when true categorizes pages where |language=<local wiki's language>; always false at en.wiki
date_name_auto_xlate_enable = false; -- when true translates English month-names to the local-wiki's language month names; always false at en.wiki
date_digit_auto_xlate_enable = false; -- when true translates Western date digit to the local-wiki's language digits (date_names['local_digits']); always false at en.wiki
global_df = get_date_format (), -- tables and variables created when this module is loaded
punct_skip = build_skip_table (punct_skip, punct_meta_params),
url_skip = build_skip_table (url_skip, url_meta_params),
aliases = aliases,
special_case_translation = special_case_translation,
date_names = date_names,
err_msg_supl = err_msg_supl,
error_conditions = error_conditions,
editor_markup_patterns = editor_markup_patterns,
et_al_patterns = et_al_patterns,
id_handlers = id_handlers,
keywords_lists = keywords_lists,
keywords_xlate = keywords_xlate,
stripmarkers=stripmarkers,
invisible_chars = invisible_chars,
invisible_defs = invisible_defs,
indic_script = indic_script,
emoji = emoji,
maint_cats = maint_cats,
messages = messages,
presentation = presentation,
prop_cats = prop_cats,
script_lang_codes = script_lang_codes,
lang_code_remap = lang_code_remap,
lang_name_remap = lang_name_remap,
this_wiki_code = this_wiki_code,
title_types = title_types,
uncategorized_namespaces = uncategorized_namespaces,
uncategorized_subpages = uncategorized_subpages,
templates_using_volume = templates_using_volume,
templates_using_issue = templates_using_issue,
templates_not_using_page = templates_not_using_page,
vol_iss_pg_patterns = vol_iss_pg_patterns,
inter_wiki_map = inter_wiki_map,
mw_languages_by_tag_t = mw_languages_by_tag_t,
mw_languages_by_name_t = mw_languages_by_name_t,
citation_class_map_t = citation_class_map_t,
citation_issue_t = citation_issue_t,
citation_no_volume_t = citation_no_volume_t,
}
eece11b3085eb39f5bb266336c4c5afa7a6eaa74
Module:Citation/CS1/Whitelist
828
52
120
119
2022-09-04T15:24:35Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[--------------------------< S U P P O R T E D P A R A M E T E R S >--------------------------------------
Because a steady-state signal conveys no useful information, whitelist.basic_arguments[] list items can have three values:
true - these parameters are valid and supported parameters
false - these parameters are deprecated but still supported
tracked - these parameters are valid and supported parameters tracked in an eponymous properties category
nil - these parameters are no longer supported. remove entirely
]]
local basic_arguments = {
['accessdate'] = true,
['access-date'] = true,
['agency'] = true,
['archivedate'] = true,
['archive-date'] = true,
['archive-format'] = true,
['archiveurl'] = true,
['archive-url'] = true,
['article'] = true,
['article-format'] = true,
['article-url'] = true,
['article-url-access'] = true,
['arxiv'] = true, -- cite arxiv; here because allowed in cite ... as identifier
['asin'] = true,
['ASIN'] = true,
['asin-tld'] = true,
['at'] = true,
['author'] = true,
['author-first'] = true,
['author-given'] = true,
['author-last'] = true,
['author-surname'] = true,
['authorlink'] = true,
['author-link'] = true,
['author-mask'] = true,
['authors'] = true,
['bibcode'] = true,
['bibcode-access'] = true,
['biorxiv'] = true, -- cite biorxiv; here because allowed in cite ... as identifier
['chapter'] = true,
['chapter-format'] = true,
['chapter-url'] = true,
['chapter-url-access'] = true,
['citeseerx'] = true, -- cite citeseerx; here because allowed in cite ... as identifier
['collaboration'] = true,
['contribution'] = true,
['contribution-format'] = true,
['contribution-url'] = true,
['contribution-url-access'] = true,
['contributor'] = true,
['contributor-first'] = true,
['contributor-given'] = true,
['contributor-last'] = true,
['contributor-surname'] = true,
['contributor-link'] = true,
['contributor-mask'] = true,
['date'] = true,
['department'] = true,
['df'] = true,
['dictionary'] = true,
['display-authors'] = true,
['display-contributors'] = true,
['display-editors'] = true,
['display-interviewers'] = true,
['display-subjects'] = true,
['display-translators'] = true,
['doi'] = true,
['DOI'] = true,
['doi-access'] = true,
['doi-broken-date'] = true,
['edition'] = true,
['editor'] = true,
['editor-first'] = true,
['editor-given'] = true,
['editor-last'] = true,
['editor-surname'] = true,
['editor-link'] = true,
['editor-mask'] = true,
['eissn'] = true,
['EISSN'] = true,
['encyclopaedia'] = true,
['encyclopedia'] = true,
['entry'] = true,
['entry-format'] = true,
['entry-url'] = true,
['entry-url-access'] = true,
['eprint'] = true, -- cite arxiv; here because allowed in cite ... as identifier
['first'] = true,
['format'] = true,
['given'] = true,
['hdl'] = true,
['HDL'] = true,
['hdl-access'] = true,
['host'] = true, -- unique to certain templates?
['id'] = true,
['ID'] = true,
['institution'] = true, -- constrain to cite thesis?
['interviewer'] = true,
['interviewer-first'] = true,
['interviewer-given'] = true,
['interviewer-last'] = true,
['interviewer-surname'] = true,
['interviewer-link'] = true,
['interviewer-mask'] = true,
['isbn'] = true,
['ISBN'] = true,
['ismn'] = true,
['ISMN'] = true,
['issn'] = true,
['ISSN'] = true,
['issue'] = true,
['jfm'] = true,
['JFM'] = true,
['journal'] = true,
['jstor'] = true,
['JSTOR'] = true,
['jstor-access'] = true,
['lang'] = true,
['language'] = true,
['last'] = true,
['lay-date'] = false,
['lay-format'] = false,
['lay-source'] = false,
['lay-url'] = false,
['lccn'] = true,
['LCCN'] = true,
['location'] = true,
['magazine'] = true,
['medium'] = true,
['minutes'] = true, -- constrain to cite AV media and podcast?
['mode'] = true,
['mr'] = true,
['MR'] = true,
['name-list-style'] = true,
['newspaper'] = true,
['no-pp'] = true,
['no-tracking'] = true,
['number'] = true,
['oclc'] = true,
['OCLC'] = true,
['ol'] = true,
['OL'] = true,
['ol-access'] = true,
['orig-date'] = true,
['origyear'] = true,
['orig-year'] = true,
['osti'] = true,
['OSTI'] = true,
['osti-access'] = true,
['others'] = true,
['p'] = true,
['page'] = true,
['pages'] = true,
['people'] = true,
['periodical'] = true,
['place'] = true,
['pmc'] = true,
['PMC'] = true,
['pmc-embargo-date'] = true,
['pmid'] = true,
['PMID'] = true,
['postscript'] = true,
['pp'] = true,
['publication-date'] = true,
['publication-place'] = true,
['publisher'] = true,
['quotation'] = true,
['quote'] = true,
['quote-page'] = true,
['quote-pages'] = true,
['ref'] = true,
['rfc'] = true,
['RFC'] = true,
['sbn'] = true,
['SBN'] = true,
['scale'] = true,
['script-article'] = true,
['script-chapter'] = true,
['script-contribution'] = true,
['script-entry'] = true,
['script-journal'] = true,
['script-magazine'] = true,
['script-newspaper'] = true,
['script-periodical'] = true,
['script-quote'] = true,
['script-section'] = true,
['script-title'] = true,
['script-website'] = true,
['script-work'] = true,
['section'] = true,
['section-format'] = true,
['section-url'] = true,
['section-url-access'] = true,
['series'] = true,
['ssrn'] = true, -- cite ssrn; these three here because allowed in cite ... as identifier
['SSRN'] = true,
['ssrn-access'] = true,
['subject'] = true,
['subject-link'] = true,
['subject-mask'] = true,
['surname'] = true,
['s2cid'] = true,
['S2CID'] = true,
['s2cid-access'] = true,
['template-doc-demo'] = true,
['time'] = true, -- constrain to cite av media and podcast?
['time-caption'] = true, -- constrain to cite av media and podcast?
['title'] = true,
['title-link'] = true,
['translator'] = true,
['translator-first'] = true,
['translator-given'] = true,
['translator-last'] = true,
['translator-surname'] = true,
['translator-link'] = true,
['translator-mask'] = true,
['trans-article'] = true,
['trans-chapter'] = true,
['trans-contribution'] = true,
['trans-entry'] = true,
['trans-journal'] = true,
['trans-magazine'] = true,
['trans-newspaper'] = true,
['trans-periodical'] = true,
['trans-quote'] = true,
['trans-section'] = true,
['trans-title'] = true,
['trans-website'] = true,
['trans-work'] = true,
['type'] = true,
['url'] = true,
['URL'] = true,
['url-access'] = true,
['url-status'] = true,
['vauthors'] = true,
['veditors'] = true,
['version'] = true,
['via'] = true,
['volume'] = true,
['website'] = true,
['work'] = true,
['year'] = true,
['zbl'] = true,
['ZBL'] = true,
}
local numbered_arguments = {
['author#'] = true,
['author-first#'] = true,
['author#-first'] = true,
['author-given#'] = true,
['author#-given'] = true,
['author-last#'] = true,
['author#-last'] = true,
['author-surname#'] = true,
['author#-surname'] = true,
['author-link#'] = true,
['author#-link'] = true,
['authorlink#'] = true,
['author#link'] = true,
['author-mask#'] = true,
['author#-mask'] = true,
['contributor#'] = true,
['contributor-first#'] = true,
['contributor#-first'] = true,
['contributor-given#'] = true,
['contributor#-given'] = true,
['contributor-last#'] = true,
['contributor#-last'] = true,
['contributor-surname#'] = true,
['contributor#-surname'] = true,
['contributor-link#'] = true,
['contributor#-link'] = true,
['contributor-mask#'] = true,
['contributor#-mask'] = true,
['editor#'] = true,
['editor-first#'] = true,
['editor#-first'] = true,
['editor-given#'] = true,
['editor#-given'] = true,
['editor-last#'] = true,
['editor#-last'] = true,
['editor-surname#'] = true,
['editor#-surname'] = true,
['editor-link#'] = true,
['editor#-link'] = true,
['editor-mask#'] = true,
['editor#-mask'] = true,
['first#'] = true,
['given#'] = true,
['host#'] = true,
['interviewer#'] = true,
['interviewer-first#'] = true,
['interviewer#-first'] = true,
['interviewer-given#'] = true,
['interviewer#-given'] = true,
['interviewer-last#'] = true,
['interviewer#-last'] = true,
['interviewer-surname#'] = true,
['interviewer#-surname'] = true,
['interviewer-link#'] = true,
['interviewer#-link'] = true,
['interviewer-mask#'] = true,
['interviewer#-mask'] = true,
['last#'] = true,
['subject#'] = true,
['subject-link#'] = true,
['subject#-link'] = true,
['subject-mask#'] = true,
['subject#-mask'] = true,
['surname#'] = true,
['translator#'] = true,
['translator-first#'] = true,
['translator#-first'] = true,
['translator-given#'] = true,
['translator#-given'] = true,
['translator-last#'] = true,
['translator#-last'] = true,
['translator-surname#'] = true,
['translator#-surname'] = true,
['translator-link#'] = true,
['translator#-link'] = true,
['translator-mask#'] = true,
['translator#-mask'] = true,
}
--[[--------------------------< P R E P R I N T S U P P O R T E D P A R A M E T E R S >--------------------
Cite arXiv, cite biorxiv, cite citeseerx, and cite ssrn are preprint templates that use the limited set of parameters
defined in the limited_basic_arguments and limited_numbered_arguments tables. Those lists are supplemented with a
template-specific list of parameters that are required by the particular template and may be exclusive to one of the
preprint templates. Some of these parameters may also be available to the general cs1|2 templates.
Same conventions for true/false/tracked/nil as above.
]]
local preprint_arguments = {
arxiv = {
['arxiv'] = true, -- cite arxiv and arxiv identifiers
['class'] = true,
['eprint'] = true, -- cite arxiv and arxiv identifiers
},
biorxiv = {
['biorxiv'] = true,
},
citeseerx = {
['citeseerx'] = true,
},
ssrn = {
['ssrn'] = true,
['SSRN'] = true,
['ssrn-access'] = true,
},
}
--[[--------------------------< L I M I T E D S U P P O R T E D P A R A M E T E R S >----------------------
cite arxiv, cite biorxiv, cite citeseerx, and cite ssrn templates are preprint templates so are allowed only a
limited subset of parameters allowed to all other cs1|2 templates. The limited subset is defined here.
Same conventions for true/false/tracked/nil as above.
]]
local limited_basic_arguments = {
['at'] = true,
['author'] = true,
['author-first'] = true,
['author-given'] = true,
['author-last'] = true,
['author-surname'] = true,
['author-link'] = true,
['authorlink'] = true,
['author-mask'] = true,
['authors'] = true,
['collaboration'] = true,
['date'] = true,
['df'] = true,
['display-authors'] = true,
['first'] = true,
['given'] = true,
['language'] = true,
['last'] = true,
['mode'] = true,
['name-list-style'] = true,
['no-tracking'] = true,
['p'] = true,
['page'] = true,
['pages'] = true,
['postscript'] = true,
['pp'] = true,
['quotation'] = true,
['quote'] = true,
['ref'] = true,
['surname'] = true,
['template-doc-demo'] = true,
['title'] = true,
['trans-title'] = true,
['vauthors'] = true,
['year'] = true,
}
local limited_numbered_arguments = {
['author#'] = true,
['author-first#'] = true,
['author#-first'] = true,
['author-given#'] = true,
['author#-given'] = true,
['author-last#'] = true,
['author#-last'] = true,
['author-surname#'] = true,
['author#-surname'] = true,
['author-link#'] = true,
['author#-link'] = true,
['authorlink#'] = true,
['author#link'] = true,
['author-mask#'] = true,
['author#-mask'] = true,
['first#'] = true,
['given#'] = true,
['last#'] = true,
['surname#'] = true,
}
--[[--------------------------< U N I Q U E _ A R G U M E N T S >----------------------------------------------
Some templates have unique parameters. Those templates and their unique parameters are listed here. Keys in this
table are the template's CitationClass parameter value
Same conventions for true/false/tracked/nil as above.
]]
local unique_arguments = {
['audio-visual'] = {
['transcript'] = true,
['transcript-format'] = true,
['transcript-url'] = true,
},
conference = {
['book-title'] = true,
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['event'] = true,
},
episode = {
['airdate'] = true,
['air-date'] = true,
['credits'] = true,
['episode-link'] = true, -- alias of |title-link=
['network'] = true,
['season'] = true,
['series-link'] = true,
['series-no'] = true,
['series-number'] = true,
['station'] = true,
['transcript'] = true,
['transcript-format'] = true,
['transcripturl'] = false,
['transcript-url'] = true,
},
mailinglist = {
['mailing-list'] = true,
},
map = {
['cartography'] = true,
['inset'] = true,
['map'] = true,
['map-format'] = true,
['map-url'] = true,
['map-url-access'] = true,
['script-map'] = true,
['sections'] = true,
['sheet'] = true,
['sheets'] = true,
['trans-map'] = true,
},
newsgroup = {
['message-id'] = true,
['newsgroup'] = true,
},
report = {
['docket'] = true,
},
serial = {
['airdate'] = true,
['air-date'] = true,
['credits'] = true,
['episode'] = true, -- cite serial only TODO: make available to cite episode?
['episode-link'] = true, -- alias of |title-link=
['network'] = true,
['series-link'] = true,
['station'] = true,
},
speech = {
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['event'] = true,
},
thesis = {
['degree'] = true,
['docket'] = true,
},
}
--[[--------------------------< T E M P L A T E _ L I S T _ G E T >--------------------------------------------
gets a list of the templates from table t
]]
local function template_list_get (t)
local out = {}; -- a table for output
for k, _ in pairs (t) do -- spin through the table and collect the keys
table.insert (out, k) -- add each key to the output table
end
return out; -- and done
end
--[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------
]]
return {
basic_arguments = basic_arguments,
numbered_arguments = numbered_arguments,
limited_basic_arguments = limited_basic_arguments,
limited_numbered_arguments = limited_numbered_arguments,
preprint_arguments = preprint_arguments,
preprint_template_list = template_list_get (preprint_arguments), -- make a template list from preprint_arguments{} table
unique_arguments = unique_arguments,
unique_param_template_list = template_list_get (unique_arguments), -- make a template list from unique_arguments{} table
};
6773846564c816e7f9eae451b65436cbda849bc5
Module:Citation/CS1/Utilities
828
53
122
121
2022-09-04T15:24:35Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local z = {
error_cats_t = {}; -- for categorizing citations that contain errors
error_ids_t = {}; -- list of error identifiers; used to prevent duplication of certain errors; local to this module
error_msgs_t = {}; -- sequence table of error messages
maint_cats_t = {}; -- for categorizing citations that aren't erroneous per se, but could use a little work
prop_cats_t = {}; -- for categorizing citations based on certain properties, language of source for instance
prop_keys_t = {}; -- for adding classes to the citation's <cite> tag
};
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
]]
local function is_set (var)
return not (var == nil or var == '');
end
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
Whether needle is in haystack
]]
local function in_array (needle, haystack)
if needle == nil then
return false;
end
for n, v in ipairs (haystack) do
if v == needle then
return n;
end
end
return false;
end
--[[--------------------------< H A S _ A C C E P T _ A S _ W R I T T E N >------------------------------------
When <str> is wholly wrapped in accept-as-written markup, return <str> without markup and true; return <str> and false else
with allow_empty = false, <str> must have at least one character inside the markup
with allow_empty = true, <str> the markup frame can be empty like (()) to distinguish an empty template parameter from the specific condition "has no applicable value" in citation-context.
After further evaluation the two cases might be merged at a later stage, but should be kept separated for now.
]]
local function has_accept_as_written (str, allow_empty)
if not is_set (str) then
return str, false;
end
local count;
if true == allow_empty then
str, count = str:gsub ('^%(%((.*)%)%)$', '%1'); -- allows (()) to be an empty set
else
str, count = str:gsub ('^%(%((.+)%)%)$', '%1');
end
return str, 0 ~= count;
end
--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------
Populates numbered arguments in a message string using an argument table. <args> may be a single string or a
sequence table of multiple strings.
]]
local function substitute (msg, args)
return args and mw.message.newRawMessage (msg, args):plain() or msg;
end
--[[--------------------------< E R R O R _ C O M M E N T >----------------------------------------------------
Wraps error messages with CSS markup according to the state of hidden. <content> may be a single string or a
sequence table of multiple strings.
]]
local function error_comment (content, hidden)
return substitute (hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content);
end
--[[--------------------------< H Y P H E N _ T O _ D A S H >--------------------------------------------------
Converts a hyphen to a dash under certain conditions. The hyphen must separate
like items; unlike items are returned unmodified. These forms are modified:
letter - letter (A - B)
digit - digit (4-5)
digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
letterdigit - letterdigit (A1-A5) (an optional separator between letter and
digit is supported – a.1-a.5 or a-1-a-5)
digitletter - digitletter (5a - 5d) (an optional separator between letter and
digit is supported – 5.a-5.d or 5-a-5-d)
any other forms are returned unmodified.
str may be a comma- or semicolon-separated list
]]
local function hyphen_to_dash (str)
if not is_set (str) then
return str;
end
local accept; -- boolean
str = str:gsub ("(%(%(.-%)%))", function(m) return m:gsub(",", ","):gsub(";", ";") end) -- replace commas and semicolons in accept-as-written markup with similar unicode characters so they'll be ignored during the split
str = str:gsub ('&[nm]dash;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace HTML numeric entity with hyphen character
str = str:gsub (' ', ' '); -- replace entity with generic keyboard space character
local out = {};
local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any
for _, item in ipairs (list) do -- for each item in the list
item, accept = has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item
if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators
if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit)
item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter)
item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit
item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit
item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter
item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters
else
item = mw.ustring.gsub (item, '%s*[–—]%s*', '–'); -- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace
end
end
table.insert (out, item); -- add the (possibly modified) item to the output table
end
local temp_str = ''; -- concatenate the output table into a comma separated string
temp_str, accept = has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out
if accept then
temp_str = has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value
return temp_str:gsub(",", ","):gsub(";", ";");
else
return temp_str:gsub(",", ","):gsub(";", ";"); -- else, return assembled temp_str
end
end
--[=[-------------------------< M A K E _ W I K I L I N K >----------------------------------------------------
Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only
link is provided (or link and display are the same), returns a wikilink in the form [[L]]; if neither are
provided or link is omitted, returns an empty string.
]=]
local function make_wikilink (link, display)
if not is_set (link) then return '' end
if is_set (display) and link ~= display then
return table.concat ({'[[', link, '|', display, ']]'});
else
return table.concat ({'[[', link, ']]'});
end
end
--[[--------------------------< S E T _ M E S S A G E >----------------------------------------------------------
Sets an error message using the ~/Configuration error_conditions{} table along with arguments supplied in the function
call, inserts the resulting message in z.error_msgs_t{} sequence table, and returns the error message.
<error_id> – key value for appropriate error handler in ~/Configuration error_conditions{} table
<arguments> – may be a single string or a sequence table of multiple strings to be subsititued into error_conditions[error_id].message
<raw> – boolean
true – causes this function to return the error message not wrapped in visible-error, hidden-error span tag;
returns error_conditions[error_id].hidden as a second return value
does not add message to z.error_msgs_t sequence table
false, nil – adds message wrapped in visible-error, hidden-error span tag to z.error_msgs_t
returns the error message wrapped in visible-error, hidden-error span tag; there is no second return value
<prefix> – string to be prepended to <message> -- TODO: remove support for these unused(?) arguments?
<suffix> – string to be appended to <message>
TODO: change z.error_cats_t and z.maint_cats_t to have the form cat_name = true? this to avoid dups without having to have an extra table
]]
local added_maint_cats = {} -- list of maintenance categories that have been added to z.maint_cats_t; TODO: figure out how to delete this table
local function set_message (error_id, arguments, raw, prefix, suffix)
local error_state = cfg.error_conditions[error_id];
prefix = prefix or '';
suffix = suffix or '';
if error_state == nil then
error (cfg.messages['undefined_error'] .. ': ' .. error_id); -- because missing error handler in Module:Citation/CS1/Configuration
elseif is_set (error_state.category) then
if error_state.message then -- when error_state.message defined, this is an error message
table.insert (z.error_cats_t, error_state.category);
else
if not added_maint_cats[error_id] then
added_maint_cats[error_id] = true; -- note that we've added this category
table.insert (z.maint_cats_t, substitute (error_state.category, arguments)); -- make cat name then add to table
end
return; -- because no message, nothing more to do
end
end
local message = substitute (error_state.message, arguments);
message = table.concat (
{
message,
' (',
make_wikilink (
table.concat (
{
cfg.messages['help page link'],
'#',
error_state.anchor
}),
cfg.messages['help page label']),
')'
});
z.error_ids_t[error_id] = true;
if z.error_ids_t['err_citation_missing_title'] and -- if missing-title error already noted
in_array (error_id, {'err_bare_url_missing_title', 'err_trans_missing_title'}) then -- and this error is one of these
return '', false; -- don't bother because one flavor of missing title is sufficient
end
message = table.concat ({prefix, message, suffix});
if true == raw then
return message, error_state.hidden; -- return message not wrapped in visible-error, hidden-error span tag
end
message = error_comment (message, error_state.hidden); -- wrap message in visible-error, hidden-error span tag
table.insert (z.error_msgs_t, message); -- add it to the messages sequence table
return message; -- and done; return value generally not used but is used as a flag in various functions of ~/Identifiers
end
--[[-------------------------< I S _ A L I A S _ U S E D >-----------------------------------------------------
This function is used by select_one() to determine if one of a list of alias parameters is in the argument list
provided by the template.
Input:
args – pointer to the arguments table from calling template
alias – one of the list of possible aliases in the aliases lists from Module:Citation/CS1/Configuration
index – for enumerated parameters, identifies which one
enumerated – true/false flag used to choose how enumerated aliases are examined
value – value associated with an alias that has previously been selected; nil if not yet selected
selected – the alias that has previously been selected; nil if not yet selected
error_list – list of aliases that are duplicates of the alias already selected
Returns:
value – value associated with alias we selected or that was previously selected or nil if an alias not yet selected
selected – the alias we selected or the alias that was previously selected or nil if an alias not yet selected
]]
local function is_alias_used (args, alias, index, enumerated, value, selected, error_list)
if enumerated then -- is this a test for an enumerated parameters?
alias = alias:gsub ('#', index); -- replace '#' with the value in index
else
alias = alias:gsub ('#', ''); -- remove '#' if it exists
end
if is_set (args[alias]) then -- alias is in the template's argument list
if value ~= nil and selected ~= alias then -- if we have already selected one of the aliases
local skip;
for _, v in ipairs (error_list) do -- spin through the error list to see if we've added this alias
if v == alias then
skip = true;
break; -- has been added so stop looking
end
end
if not skip then -- has not been added so
table.insert (error_list, alias); -- add error alias to the error list
end
else
value = args[alias]; -- not yet selected an alias, so select this one
selected = alias;
end
end
return value, selected; -- return newly selected alias, or previously selected alias
end
--[[--------------------------< A D D _ M A I N T _ C A T >------------------------------------------------------
Adds a category to z.maint_cats_t using names from the configuration file with additional text if any.
To prevent duplication, the added_maint_cats table lists the categories by key that have been added to z.maint_cats_t.
]]
local function add_maint_cat (key, arguments)
if not added_maint_cats [key] then
added_maint_cats [key] = true; -- note that we've added this category
table.insert (z.maint_cats_t, substitute (cfg.maint_cats [key], arguments)); -- make name then add to table
end
end
--[[--------------------------< A D D _ P R O P _ C A T >--------------------------------------------------------
Adds a category to z.prop_cats_t using names from the configuration file with additional text if any.
foreign_lang_source and foreign_lang_source_2 keys have a language code appended to them so that multiple languages
may be categorized but multiples of the same language are not categorized.
added_prop_cats is a table declared in page scope variables above
]]
local added_prop_cats = {}; -- list of property categories that have been added to z.prop_cats_t
local function add_prop_cat (key, arguments, key_modifier)
local key_modified = key .. ((key_modifier and key_modifier) or ''); -- modify <key> with <key_modifier> if present and not nil
if not added_prop_cats [key_modified] then
added_prop_cats [key_modified] = true; -- note that we've added this category
table.insert (z.prop_cats_t, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table
table.insert (z.prop_keys_t, 'cs1-prop-' .. key); -- convert key to class for use in the citation's <cite> tag
end
end
--[[--------------------------< S A F E _ F O R _ I T A L I C S >----------------------------------------------
Protects a string that will be wrapped in wiki italic markup '' ... ''
Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that
they will be inverted (i.e. unitalicized) in the resulting references. In addition, <i> and '' tend to interact
poorly under Mediawiki's HTML tidy.
]]
local function safe_for_italics (str)
if not is_set (str) then return str end
if str:sub (1, 1) == "'" then str = "<span></span>" .. str; end
if str:sub (-1, -1) == "'" then str = str .. "<span></span>"; end
return str:gsub ('\n', ' '); -- Remove newlines as they break italics.
end
--[[--------------------------< W R A P _ S T Y L E >----------------------------------------------------------
Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one
argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason
this function is similar to but separate from wrap_msg().
]]
local function wrap_style (key, str)
if not is_set (str) then
return "";
elseif in_array (key, {'italic-title', 'trans-italic-title'}) then
str = safe_for_italics (str);
end
return substitute (cfg.presentation[key], {str});
end
--[[--------------------------< M A K E _ S E P _ L I S T >------------------------------------------------------------
make a separated list of items using provided separators.
<sep_list> - typically '<comma><space>'
<sep_list_pair> - typically '<space>and<space>'
<sep_list_end> - typically '<comma><space>and<space>' or '<comma><space>&<space>'
defaults to cfg.presentation['sep_list'], cfg.presentation['sep_list_pair'], and cfg.presentation['sep_list_end']
if <sep_list_end> is specified, <sep_list> and <sep_list_pair> must also be supplied
]]
local function make_sep_list (count, list_seq, sep_list, sep_list_pair, sep_list_end)
local list = '';
if not sep_list then -- set the defaults
sep_list = cfg.presentation['sep_list'];
sep_list_pair = cfg.presentation['sep_list_pair'];
sep_list_end = cfg.presentation['sep_list_end'];
end
if 2 >= count then
list = table.concat (list_seq, sep_list_pair); -- insert separator between two items; returns list_seq[1] then only one item
elseif 2 < count then
list = table.concat (list_seq, sep_list, 1, count - 1); -- concatenate all but last item with plain list separator
list = table.concat ({list, list_seq[count]}, sep_list_end); -- concatenate last item onto end of <list> with final separator
end
return list;
end
--[[--------------------------< S E L E C T _ O N E >----------------------------------------------------------
Chooses one matching parameter from a list of parameters to consider. The list of parameters to consider is just
names. For parameters that may be enumerated, the position of the numerator in the parameter name is identified
by the '#' so |author-last1= and |author1-last= are represented as 'author-last#' and 'author#-last'.
Because enumerated parameter |<param>1= is an alias of |<param>= we must test for both possibilities.
Generates an error if more than one match is present.
]]
local function select_one (args, aliases_list, error_condition, index)
local value = nil; -- the value assigned to the selected parameter
local selected = ''; -- the name of the parameter we have chosen
local error_list = {};
if index ~= nil then index = tostring(index); end
for _, alias in ipairs (aliases_list) do -- for each alias in the aliases list
if alias:match ('#') then -- if this alias can be enumerated
if '1' == index then -- when index is 1 test for enumerated and non-enumerated aliases
value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- first test for non-enumerated alias
end
value, selected = is_alias_used (args, alias, index, true, value, selected, error_list); -- test for enumerated alias
else
value, selected = is_alias_used (args, alias, index, false, value, selected, error_list); -- test for non-enumerated alias
end
end
if #error_list > 0 and 'none' ~= error_condition then -- for cases where this code is used outside of extract_names()
for i, v in ipairs (error_list) do
error_list[i] = wrap_style ('parameter', v);
end
table.insert (error_list, wrap_style ('parameter', selected));
set_message (error_condition, {make_sep_list (#error_list, error_list)});
end
return value, selected;
end
--[=[-------------------------< R E M O V E _ W I K I _ L I N K >----------------------------------------------
Gets the display text from a wikilink like [[A|B]] or [[B]] gives B
The str:gsub() returns either A|B froma [[A|B]] or B from [[B]] or B from B (no wikilink markup).
In l(), l:gsub() removes the link and pipe (if they exist); the second :gsub() trims whitespace from the label
if str was wrapped in wikilink markup. Presumably, this is because without wikimarkup in str, there is no match
in the initial gsub, the replacement function l() doesn't get called.
]=]
local function remove_wiki_link (str)
return (str:gsub ("%[%[([^%[%]]*)%]%]", function(l)
return l:gsub ("^[^|]*|(.*)$", "%1" ):gsub ("^%s*(.-)%s*$", "%1");
end));
end
--[=[-------------------------< I S _ W I K I L I N K >--------------------------------------------------------
Determines if str is a wikilink, extracts, and returns the wikilink type, link text, and display text parts.
If str is a complex wikilink ([[L|D]]):
returns wl_type 2 and D and L from [[L|D]];
if str is a simple wikilink ([[D]])
returns wl_type 1 and D from [[D]] and L as empty string;
if not a wikilink:
returns wl_type 0, str as D, and L as empty string.
trims leading and trailing whitespace and pipes from L and D ([[L|]] and [[|D]] are accepted by MediaWiki and
treated like [[D]]; while [[|D|]] is not accepted by MediaWiki, here, we accept it and return D without the pipes).
]=]
local function is_wikilink (str)
local D, L
local wl_type = 2; -- assume that str is a complex wikilink [[L|D]]
if not str:match ('^%[%[[^%]]+%]%]$') then -- is str some sort of a wikilink (must have some sort of content)
return 0, str, ''; -- not a wikilink; return wl_type as 0, str as D, and empty string as L
end
L, D = str:match ('^%[%[([^|]+)|([^%]]+)%]%]$'); -- get L and D from [[L|D]]
if not is_set (D) then -- if no separate display
D = str:match ('^%[%[([^%]]*)|*%]%]$'); -- get D from [[D]] or [[D|]]
wl_type = 1;
end
D = mw.text.trim (D, '%s|'); -- trim white space and pipe characters
return wl_type, D, L or '';
end
--[[--------------------------< S T R I P _ A P O S T R O P H E _ M A R K U P >--------------------------------
Strip wiki italic and bold markup from argument so that it doesn't contaminate COinS metadata.
This function strips common patterns of apostrophe markup. We presume that editors who have taken the time to
markup a title have, as a result, provided valid markup. When they don't, some single apostrophes are left behind.
Returns the argument without wiki markup and a number; the number is more-or-less meaningless except as a flag
to indicate that markup was replaced; do not rely on it as an indicator of how many of any kind of markup was
removed; returns the argument and nil when no markup removed
]]
local function strip_apostrophe_markup (argument)
if not is_set (argument) then
return argument, nil; -- no argument, nothing to do
end
if nil == argument:find ( "''", 1, true ) then -- Is there at least one double apostrophe? If not, exit.
return argument, nil;
end
local flag;
while true do
if argument:find ("'''''", 1, true) then -- bold italic (5)
argument, flag = argument:gsub ("%'%'%'%'%'", ""); -- remove all instances of it
elseif argument:find ("''''", 1, true) then -- italic start and end without content (4)
argument, flag=argument:gsub ("%'%'%'%'", "");
elseif argument:find ("'''", 1, true) then -- bold (3)
argument, flag=argument:gsub ("%'%'%'", "");
elseif argument:find ("''", 1, true) then -- italic (2)
argument, flag = argument:gsub ("%'%'", "");
else
break;
end
end
return argument, flag; -- done
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr)
cfg = cfg_table_ptr;
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
add_maint_cat = add_maint_cat, -- exported functions
add_prop_cat = add_prop_cat,
error_comment = error_comment,
has_accept_as_written = has_accept_as_written,
hyphen_to_dash = hyphen_to_dash,
in_array = in_array,
is_set = is_set,
is_wikilink = is_wikilink,
make_sep_list = make_sep_list,
make_wikilink = make_wikilink,
remove_wiki_link = remove_wiki_link,
safe_for_italics = safe_for_italics,
select_one = select_one,
set_message = set_message,
set_selected_modules = set_selected_modules,
strip_apostrophe_markup = strip_apostrophe_markup,
substitute = substitute,
wrap_style = wrap_style,
z = z, -- exported table
}
b006801b48981b2987f20fc09cbe0dfda525e044
Module:Citation/CS1/Date validation
828
54
124
123
2022-09-04T15:24:36Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local add_prop_cat, is_set, in_array, set_message, substitute, wrap_style; -- imported functions from selected Module:Citation/CS1/Utilities
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration
--[[--------------------------< F I L E - S C O P E D E C L A R A T I O N S >--------------------------------
File-scope variables are declared here
]]
local lang_object = mw.getContentLanguage(); -- used by is_valid_accessdate(), is_valid_year(), date_name_xlate(); TODO: move to ~/Configuration?
local year_limit; -- used by is_valid_year()
--[=[-------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
returns true if:
Wikipedia start date <= accessdate < today + 2 days
Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time)
accessdate is the date provided in |access-date= at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
if today is 2015-01-01T00:00:00 then
adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser
apparently doesn't understand non-English date month names. This function will always return false when the date
contains a non-English month name because good1 is false after the call to lang.formatDate(). To get around that
call this function with YYYY-MM-DD format dates.
]=]
local function is_valid_accessdate (accessdate)
local good1, good2;
local access_ts, tomorrow_ts; -- to hold Unix time stamps representing the dates
good1, access_ts = pcall (lang_object.formatDate, lang_object, 'U', accessdate ); -- convert accessdate value to Unix timestamp
good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand
access_ts = tonumber (access_ts) or lang_object:parseFormattedNumber (access_ts); -- convert to numbers for the comparison;
tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts);
else
return false; -- one or both failed to convert to Unix time stamp
end
if 979516800 <= access_ts and access_ts < tomorrow_ts then -- Wikipedia start date <= accessdate < tomorrow's date
return true;
else
return false; -- accessdate out of range
end
end
--[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------
returns a number according to the month in a date: 1 for January, etc. Capitalization and spelling must be correct.
If not a valid month, returns 0
]]
local function get_month_number (month)
return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or -- look for local names first
cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or -- failing that, look for English names
0; -- not a recognized month name
end
--[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------
returns a number according to the sequence of seasons in a year: 21 for Spring, etc. Capitalization and spelling
must be correct. If not a valid season, returns 0.
21-24 = Spring, Summer, Autumn, Winter, independent of “Hemisphere”
returns 0 when <param> is not |date=
Season numbering is defined by Extended Date/Time Format (EDTF) specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using
numbers 21-41. cs1|2 only supports generic seasons. EDTF does support the distinction between north and south
hemisphere seasons but cs1|2 has no way to make that distinction.
These additional divisions not currently supported:
25-28 = Spring - Northern Hemisphere, Summer- Northern Hemisphere, Autumn - Northern Hemisphere, Winter - Northern Hemisphere
29-32 = Spring – Southern Hemisphere, Summer– Southern Hemisphere, Autumn – Southern Hemisphere, Winter - Southern Hemisphere
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
37-39 = Quadrimester 1, Quadrimester 2, Quadrimester 3 (4 months each)
40-41 = Semestral 1, Semestral-2 (6 months each)
]]
local function get_season_number (season, param)
if 'date' ~= param then
return 0; -- season dates only supported by |date=
end
return cfg.date_names['local'].season[season] or -- look for local names first
cfg.date_names['en'].season[season] or -- failing that, look for English names
0; -- not a recognized season name
end
--[[--------------------------< G E T _ Q U A R T E R _ N U M B E R >------------------------------------------
returns a number according to the sequence of quarters in a year: 33 for first quarter, etc. Capitalization and spelling
must be correct. If not a valid quarter, returns 0.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
returns 0 when <param> is not |date=
Quarter numbering is defined by Extended Date/Time Format (EDTF) specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using
numbers 21-41. cs1|2 only supports generic seasons and quarters.
These additional divisions not currently supported:
37-39 = Quadrimester 1, Quadrimester 2, Quadrimester 3 (4 months each)
40-41 = Semestral 1, Semestral-2 (6 months each)
]]
local function get_quarter_number (quarter, param)
if 'date' ~= param then
return 0; -- quarter dates only supported by |date=
end
quarter = mw.ustring.gsub (quarter, ' +', ' '); -- special case replace multiple space chars with a single space char
return cfg.date_names['local'].quarter[quarter] or -- look for local names first
cfg.date_names['en'].quarter[quarter] or -- failing that, look for English names
0; -- not a recognized quarter name
end
--[[--------------------------< G E T _ P R O P E R _ N A M E _ N U M B E R >----------------------------------
returns a non-zero number if date contains a recognized proper-name. Capitalization and spelling must be correct.
returns 0 when <param> is not |date=
]]
local function get_proper_name_number (name, param)
if 'date' ~= param then
return 0; -- proper-name dates only supported by |date=
end
return cfg.date_names['local'].named[name] or -- look for local names dates first
cfg.date_names['en'].named[name] or -- failing that, look for English names
0; -- not a recognized named date
end
--[[--------------------------< G E T _ E L E M E N T _ N U M B E R <------------------------------------------
returns true if month or season or quarter or proper name is valid (properly spelled, capitalized, abbreviated)
]]
local function get_element_number (element, param)
local num;
local funcs = {get_month_number, get_season_number, get_quarter_number, get_proper_name_number}; -- list of functions to execute in order
for _, func in ipairs (funcs) do -- spin through the function list
num = func (element, param); -- call the function and get the returned number
if 0 ~= num then -- non-zero when valid month season quarter
return num; -- return that number
end
end
return nil; -- not valid
end
--[[--------------------------< I S _ V A L I D _ Y E A R >----------------------------------------------------
Function gets current year from the server and compares it to year from a citation parameter. Years more than one
year in the future are not acceptable.
Special case for |pmc-embargo-date=: years more than two years in the future are not acceptable
]]
local function is_valid_year (year, param)
if not is_set (year_limit) then
year_limit = tonumber(os.date("%Y"))+1; -- global variable so we only have to fetch it once
end
year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to number for the comparison;
if 'pmc-embargo-date' == param then -- special case for |pmc-embargo-date=
return year and (year <= tonumber(os.date("%Y"))+2) or false; -- years more than two years in the future are not accepted
end
return year and (year <= year_limit) or false;
end
--[[--------------------------< I S _ V A L I D _ D A T E >----------------------------------------------------
Returns true if day is less than or equal to the number of days in month and year is no farther into the future
than next year; else returns false.
Assumes Julian calendar prior to year 1582 and Gregorian calendar thereafter. Accounts for Julian calendar leap
years before 1582 and Gregorian leap years after 1582. Where the two calendars overlap (1582 to approximately
1923) dates are assumed to be Gregorian.
]]
local function is_valid_date (year, month, day, param)
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
local month_length;
if not is_valid_year (year, param) then -- no farther into the future than next year except |pmc-embargo-date= no more than two years in the future
return false;
end
month = tonumber (month); -- required for YYYY-MM-DD dates
if (2 == month) then -- if February
month_length = 28; -- then 28 days unless
if 1582 > tonumber(year) then -- Julian calendar
if 0 == (year%4) then -- is a leap year?
month_length = 29; -- if leap year then 29 days in February
end
else -- Gregorian calendar
if (0 == (year%4) and (0 ~= (year%100) or 0 == (year%400))) then -- is a leap year?
month_length = 29; -- if leap year then 29 days in February
end
end
else
month_length = days_in_month[month];
end
if tonumber (day) > month_length then
return false;
end
return true;
end
--[[--------------------------< I S _ V A L I D _ M O N T H _ R A N G E _ S T Y L E >--------------------------
Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August.
This function looks in cfg.date_names{} to see if both month names are listed in the long subtable or both are
listed in the short subtable. When both have the same style (both are listed in the same table), returns true; false else
]]
local function is_valid_month_range_style (month1, month2)
if (cfg.date_names.en.long[month1] and cfg.date_names.en.long[month2]) or -- are both English names listed in the long subtable?
(cfg.date_names.en.short[month1] and cfg.date_names.en.short[month2]) or -- are both English names listed in the short subtable?
(cfg.date_names['local'].long[month1] and cfg.date_names['local'].long[month2]) or -- are both local names listed in the long subtable?
(cfg.date_names['local'].short[month1] and cfg.date_names['local'].short[month2]) then -- are both local names listed in the short subtable?
return true;
end
return false; -- names are mixed
end
--[[--------------------------< I S _ V A L I D _ M O N T H _ S E A S O N _ R A N G E >------------------------
Check a pair of months or seasons to see if both are valid members of a month or season pair.
Month pairs are expected to be left to right, earliest to latest in time.
All season ranges are accepted as valid because there are publishers out there who have published a Summer–Spring YYYY issue, hence treat as ok
]]
local function is_valid_month_season_range(range_start, range_end, param)
local range_start_number = get_month_number (range_start);
local range_end_number;
if 0 == range_start_number then -- is this a month range?
range_start_number = get_season_number (range_start, param); -- not a month; is it a season? get start season number
range_end_number = get_season_number (range_end, param); -- get end season number
if (0 ~= range_start_number) and (0 ~= range_end_number) and (range_start_number ~= range_end_number) then
return true; -- any season pairing is accepted except when both are the same
end
return false; -- range_start and/or range_end is not a season
end
-- here when range_start is a month
range_end_number = get_month_number (range_end); -- get end month number
if range_start_number < range_end_number and -- range_start is a month; does range_start precede range_end?
is_valid_month_range_style (range_start, range_end) then -- do months have the same style?
return true; -- proper order and same style
end
return false; -- range_start month number is greater than or equal to range end number; or range end isn't a month
end
--[[--------------------------< M A K E _ C O I N S _ D A T E >------------------------------------------------
This function receives a table of date parts for one or two dates and an empty table reference declared in
Module:Citation/CS1. The function is called only for |date= parameters and only if the |date=<value> is
determined to be a valid date format. The question of what to do with invalid date formats is not answered here.
The date parts in the input table are converted to an ISO 8601 conforming date string:
single whole dates: yyyy-mm-dd
month and year dates: yyyy-mm
year dates: yyyy
ranges: yyyy-mm-dd/yyyy-mm-dd
yyyy-mm/yyyy-mm
yyyy/yyyy
Dates in the Julian calendar are reduced to year or year/year so that we don't have to do calendar conversion from
Julian to Proleptic Gregorian.
The input table has:
year, year2 – always present; if before 1582, ignore months and days if present
month, month2 – 0 if not provided, 1-12 for months, 21-24 for seasons; 99 Christmas
day, day2 – 0 if not provided, 1-31 for days
the output table receives:
rftdate: an ISO 8601 formatted date
rftchron: a free-form version of the date, usually without year which is in rftdate (season ranges and proper-name dates)
rftssn: one of four season keywords: winter, spring, summer, fall (lowercase)
rftquarter: one of four values: 1, 2, 3, 4
]]
local function make_COinS_date (input, tCOinS_date)
local date; -- one date or first date in a range
local date2 = ''; -- end of range date
-- start temporary Julian / Gregorian calendar uncertainty detection
local year = tonumber(input.year); -- this temporary code to determine the extent of sources dated to the Julian/Gregorian
local month = tonumber(input.month); -- interstice 1 October 1582 – 1 January 1926
local day = tonumber (input.day);
if (0 ~= day) and -- day must have a value for this to be a whole date
(((1582 == year) and (10 <= month) and (12 >= month)) or -- any whole 1582 date from 1 October to 31 December or
((1926 == year) and (1 == month) and (1 == input.day)) or -- 1 January 1926 or
((1582 < year) and (1925 >= year))) then -- any date 1 January 1583 – 31 December 1925
tCOinS_date.inter_cal_cat = true; -- set category flag true
end
-- end temporary Julian / Gregorian calendar uncertainty detection
if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only
date = input.year;
if 0 ~= input.year2 and input.year ~= input.year2 then -- if a range, only the second year portion when not the same as range start year
date = string.format ('%.4d/%.4d', tonumber(input.year), tonumber(input.year2)) -- assemble the date range
end
if 20 < tonumber(input.month) then -- if season or proper-name date
local season = {[24] = 'winter', [21] = 'spring', [22] = 'summer', [23] = 'fall', [33] = '1', [34] = '2', [35] = '3', [36] = '4', [98] = 'Easter', [99] = 'Christmas'}; -- seasons lowercase, no autumn; proper-names use title case
if 0 == input.month2 then -- single season date
if 40 < tonumber(input.month) then
tCOinS_date.rftchron = season[input.month]; -- proper-name dates
elseif 30 < tonumber(input.month) then
tCOinS_date.rftquarter = season[input.month]; -- quarters
else
tCOinS_date.rftssn = season[input.month]; -- seasons
end
else -- season range with a second season specified
if input.year ~= input.year2 then -- season year – season year range or season year–year
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
if 0~= input.month2 then
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2);
end
else -- season–season year range
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
tCOinS_date.rftchron = season[input.month] .. '–' .. season[input.month2]; -- season–season year range
end
end
end
tCOinS_date.rftdate = date;
return; -- done
end
if 0 ~= input.day then
date = string.format ('%s-%.2d-%.2d', input.year, tonumber(input.month), tonumber(input.day)); -- whole date
elseif 0 ~= input.month then
date = string.format ('%s-%.2d', input.year, tonumber(input.month)); -- year and month
else
date = string.format ('%s', input.year); -- just year
end
if 0 ~= input.year2 then
if 0 ~= input.day2 then
date2 = string.format ('/%s-%.2d-%.2d', input.year2, tonumber(input.month2), tonumber(input.day2)); -- whole date
elseif 0 ~= input.month2 then
date2 = string.format ('/%s-%.2d', input.year2, tonumber(input.month2)); -- year and month
else
date2 = string.format ('/%s', input.year2); -- just year
end
end
tCOinS_date.rftdate = date .. date2; -- date2 has the '/' separator
return;
end
--[[--------------------------< P A T T E R N S >--------------------------------------------------------------
this is the list of patterns for date formats that this module recognizes. Approximately the first half of these
patterns represent formats that might be reformatted into another format. Those that might be reformatted have
'indicator' letters that identify the content of the matching capture: 'd' (day), 'm' (month), 'a' (anchor year),
'y' (year); second day, month, year have a '2' suffix.
These patterns are used for both date validation and for reformatting. This table should not be moved to ~/Configuration
because changes to this table require changes to check_date() and to reformatter() and reformat_date()
]]
local patterns = {
-- year-initial numerical year-month-day
['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'},
-- month-initial: month day, year
['Mdy'] = {'^(%D-) +([1-9]%d?), +((%d%d%d%d?)%a?)$', 'm', 'd', 'a', 'y'},
-- month-initial day range: month day–day, year; days are separated by endash
['Md-dy'] = {'^(%D-) +([1-9]%d?)[%-–]([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'd2', 'a', 'y'},
-- day-initial: day month year
['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'},
-- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed; not supported at en.wiki
-- ['yMd'] = {'^((%d%d%d%d?)%a?) +(%D-) +(%d%d?)$', 'a', 'y', 'm', 'd'},
-- day-range-initial: day–day month year; days are separated by endash
['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'},
-- day initial month-day-range: day month - day month year; uses spaced endash
['dM-dMy'] = {'^([1-9]%d?) +(%D-) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'd2', 'm2', 'a', 'y'},
-- month initial month-day-range: month day – month day, year; uses spaced endash
['Md-Mdy'] = {'^(%D-) +([1-9]%d?) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$','m', 'd', 'm2', 'd2', 'a', 'y'},
-- day initial month-day-year-range: day month year - day month year; uses spaced endash
['dMy-dMy'] = {'^([1-9]%d?) +(%D-) +(%d%d%d%d) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'y', 'd2', 'm2', 'a', 'y2'},
-- month initial month-day-year-range: month day, year – month day, year; uses spaced endash
['Mdy-Mdy'] = {'^(%D-) +([1-9]%d?), +(%d%d%d%d) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'y', 'm2', 'd2', 'a', 'y2'},
-- these date formats cannot be converted, per se, but month name can be rendered short or long
-- month/season year - month/season year; separated by spaced endash
['My-My'] = {'^(%D-) +(%d%d%d%d) +[%-–] +(%D-) +((%d%d%d%d)%a?)$', 'm', 'y', 'm2', 'a', 'y2'},
-- month/season range year; months separated by endash
['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'},
-- month/season year or proper-name year; quarter year when First Quarter YYYY etc.
['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, -- this way because endash is a member of %D; %D- will match January–March 2019 when it shouldn't
-- these date formats cannot be converted
['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash
['Sy-y'] = {'^(%D-) +(%d%d%d%d)[%-–]((%d%d%d%d)%a?)$'}, -- special case Winter/Summer year-year; year separated with unspaced endash
['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- year range: YYYY–YY; separated by unspaced endash
['y'] = {'^((%d%d%d%d?)%a?)$'}, -- year; here accept either YYY or YYYY
}
--[[--------------------------< I S _ V A L I D _ E M B A R G O _ D A T E >------------------------------------
returns true and date value if that value has proper dmy, mdy, ymd format.
returns false and 9999 (embargoed forever) when date value is not proper format; assumes that when |pmc-embargo-date= is
set, the editor intended to embargo a PMC but |pmc-embargo-date= does not hold a single date.
]]
local function is_valid_embargo_date (v)
if v:match (patterns['ymd'][1]) or -- ymd
v:match (patterns['Mdy'][1]) or -- dmy
v:match (patterns['dMy'][1]) then -- mdy
return true, v;
end
return false, '9999'; -- if here not good date so return false and set embargo date to long time in future
end
--[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------
Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only
allowed range separator is endash. Additionally, check the date to see that it is a real date: no 31 in 30-day
months; no 29 February when not a leap year. Months, both long-form and three character abbreviations, and seasons
must be spelled correctly. Future years beyond next year are not allowed.
If the date fails the format tests, this function returns false and does not return values for anchor_year and
COinS_date. When this happens, the date parameter is (DEBUG: not?) used in the COinS metadata and the CITEREF identifier gets
its year from the year parameter if present otherwise CITEREF does not get a date value.
Inputs:
date_string - date string from date-holding parameters (date, year, publication-date, access-date, pmc-embargo-date, archive-date, lay-date)
Returns:
false if date string is not a real date; else
true, anchor_year, COinS_date
anchor_year can be used in CITEREF anchors
COinS_date is ISO 8601 format date; see make_COInS_date()
]]
local function check_date (date_string, param, tCOinS_date)
local year; -- assume that year2, months, and days are not used;
local year2 = 0; -- second year in a year range
local month = 0;
local month2 = 0; -- second month in a month range
local day = 0;
local day2 = 0; -- second day in a day range
local anchor_year;
local coins_date;
if date_string:match (patterns['ymd'][1]) then -- year-initial numerical year month day format
year, month, day = date_string:match (patterns['ymd'][1]);
if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar
anchor_year = year;
elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year
month, day, anchor_year, year = mw.ustring.match(date_string, patterns['Mdy'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
elseif mw.ustring.match(date_string, patterns['Md-dy'][1]) then -- month-initial day range: month day–day, year; days are separated by endash
month, day, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-dy'][1]);
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same;
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
month2=month; -- for metadata
year2 = year;
elseif mw.ustring.match(date_string, patterns['dMy'][1]) then -- day-initial: day month year
day, month, anchor_year, year = mw.ustring.match(date_string, patterns['dMy'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
--[[ NOT supported at en.wiki
elseif mw.ustring.match(date_string, patterns['yMd'][1]) then -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed
anchor_year, year, month, day = mw.ustring.match(date_string, patterns['yMd'][1]);
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
-- end NOT supported at en.wiki ]]
elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash
day, day2, month, anchor_year, year = mw.ustring.match(date_string, patterns['d-dMy'][1]);
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same;
month = get_month_number (month);
if 0 == month then return false; end -- return false if month text isn't one of the twelve months
month2 = month; -- for metadata
year2 = year;
elseif mw.ustring.match(date_string, patterns['dM-dMy'][1]) then -- day initial month-day-range: day month - day month year; uses spaced endash
day, month, day2, month2, anchor_year, year = mw.ustring.match(date_string, patterns['dM-dMy'][1]);
if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later;
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
year2 = year;
elseif mw.ustring.match(date_string, patterns['Md-Mdy'][1]) then -- month initial month-day-range: month day – month day, year; uses spaced endash
month, day, month2, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-Mdy'][1]);
if (not is_valid_month_season_range(month, month2, param)) or not is_valid_year(year) then return false; end
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
year2 = year;
elseif mw.ustring.match(date_string, patterns['dMy-dMy'][1]) then -- day initial month-day-year-range: day month year - day month year; uses spaced endash
day, month, year, day2, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['dMy-dMy'][1]);
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style
month = get_month_number (month); -- for metadata
month2 = get_month_number (month2);
if 0 == month or 0 == month2 then return false; end -- both must be valid
elseif mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]) then -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash
month, day, year, month2, day2, anchor_year, year2 = mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]);
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style
month = get_month_number (month); -- for metadata
month2 = get_month_number(month2);
if 0 == month or 0 == month2 then return false; end -- both must be valid
elseif mw.ustring.match(date_string, patterns['Sy4-y2'][1]) then -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash
local century;
month, year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy4-y2'][1]);
if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
year2 = century..year2; -- add the century to year2 for comparisons
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
month = get_season_number(month, param);
elseif mw.ustring.match(date_string, patterns['Sy-y'][1]) then -- special case Winter/Summer year-year; year separated with unspaced endash
month, year, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy-y'][1]);
month = get_season_number (month, param); -- <month> can only be winter or summer; also for metadata
if (month ~= cfg.date_names['en'].season['Winter']) and (month ~= cfg.date_names['en'].season['Summer']) then
return false; -- not Summer or Winter; abandon
end
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['My-My'][1]) then -- month/season year - month/season year; separated by spaced endash
month, year, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['My-My'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
if 0 ~= get_month_number(month) and 0 ~= get_month_number(month2) and is_valid_month_range_style(month, month2) then -- both must be month year, same month style
month = get_month_number(month);
month2 = get_month_number(month2);
elseif 0 ~= get_season_number(month, param) and 0 ~= get_season_number(month2, param) then -- both must be season year, not mixed
month = get_season_number(month, param);
month2 = get_season_number(month2, param);
else
return false;
end
elseif mw.ustring.match(date_string, patterns['M-My'][1]) then -- month/season range year; months separated by endash
month, month2, anchor_year, year = mw.ustring.match(date_string, patterns['M-My'][1]);
if (not is_valid_month_season_range(month, month2, param)) or (not is_valid_year(year)) then return false; end
if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season
month = get_month_number(month);
month2 = get_month_number(month2);
if 0 == month or 0 == month2 then return false; end
else
month = get_season_number(month, param);
month2 = get_season_number(month2, param);
end
year2 = year;
elseif mw.ustring.match(date_string, patterns['My'][1]) then -- month/season/quarter/proper-name year
month, anchor_year, year = mw.ustring.match(date_string, patterns['My'][1]);
if not is_valid_year(year) then return false; end
month = get_element_number(month, param); -- get month season quarter proper-name number or nil
if not month then return false; end -- not valid whatever it is
elseif mw.ustring.match(date_string, patterns['y-y'][1]) then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
year, anchor_year, year2 = mw.ustring.match(date_string, patterns['y-y'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['y4-y2'][1]) then -- Year range: YYYY–YY; separated by unspaced endash
local century;
year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['y4-y2'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
if in_array (param, {'date', 'publication-date', 'year'}) then
add_prop_cat ('year-range-abbreviated');
end
if 13 > tonumber(year2) then return false; end -- don't allow 2003-05 which might be May 2003
year2 = century .. year2; -- add the century to year2 for comparisons
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
elseif mw.ustring.match(date_string, patterns['y'][1]) then -- year; here accept either YYY or YYYY
anchor_year, year = mw.ustring.match(date_string, patterns['y'][1]);
if false == is_valid_year(year) then
return false;
end
else
return false; -- date format not one of the MOS:DATE approved formats
end
if 'access-date' == param then -- test accessdate here because we have numerical date parts
if 0 ~= year and 0 ~= month and 0 ~= day and -- all parts of a single date required
0 == year2 and 0 == month2 and 0 == day2 then -- none of these; accessdate must not be a range
if not is_valid_accessdate(year .. '-' .. month .. '-' .. day) then
return false; -- return false when accessdate out of bounds
end
else
return false; -- return false when accessdate is a range of two dates
end
end
local result=true; -- check whole dates for validity; assume true because not all dates will go through this test
if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then -- YMD (simple whole date)
result = is_valid_date (year, month, day, param); -- <param> for |pmc-embargo-date=
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then -- YMD-d (day range)
result = is_valid_date (year, month, day);
result = result and is_valid_date (year, month, day2);
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-md (day month range)
result = is_valid_date (year, month, day);
result = result and is_valid_date (year, month2, day2);
elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 ~= year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-ymd (day month year range)
result = is_valid_date(year, month, day);
result = result and is_valid_date(year2, month2, day2);
end
if false == result then return false; end
if nil ~= tCOinS_date then -- this table only passed into this function when testing |date= parameter values
make_COinS_date ({year = year, month = month, day = day, year2 = year2, month2 = month2, day2 = day2}, tCOinS_date); -- make an ISO 8601 date string for COinS
end
return true, anchor_year; -- format is good and date string represents a real date
end
--[[--------------------------< D A T E S >--------------------------------------------------------------------
Cycle the date-holding parameters in passed table date_parameters_list through check_date() to check compliance with MOS:DATE. For all valid dates, check_date() returns
true. The |date= parameter test is unique, it is the only date holding parameter from which values for anchor_year (used in CITEREF identifiers) and COinS_date (used in
the COinS metadata) are derived. The |date= parameter is the only date-holding parameter that is allowed to contain the no-date keywords "n.d." or "nd" (without quotes).
Unlike most error messages created in this module, only one error message is created by this function. Because all of the date holding parameters are processed serially,
parameters with errors are added to the <error_list> sequence table as the dates are tested.
]]
local function dates(date_parameters_list, tCOinS_date, error_list)
local anchor_year; -- will return as nil if the date being tested is not |date=
local COinS_date; -- will return as nil if the date being tested is not |date=
local embargo_date; -- if embargo date is a good dmy, mdy, ymd date then holds original value else reset to 9999
local good_date = false;
for k, v in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(v.val) then -- if the parameter has a value
v.val = mw.ustring.gsub(v.val, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9
if v.val:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year=
local year = v.val:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested
if 'date' == k then
anchor_year, COinS_date = v.val:match("((c%. [1-9]%d%d%d?)%a?)"); -- anchor year and COinS_date only from |date= parameter
good_date = is_valid_year(year);
elseif 'year' == k then
good_date = is_valid_year(year);
end
elseif 'date' == k then -- if the parameter is |date=
if v.val:match("^n%.d%.%a?$") then -- ToDo: I18N -- if |date=n.d. with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((n%.d%.)%a?)"); -- ToDo: I18N -- "n.d."; no error when date parameter is set to no date
elseif v.val:match("^nd%a?$") then -- ToDo: I18N -- if |date=nd with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((nd)%a?)"); -- ToDo: I18N -- "nd"; no error when date parameter is set to no date
else
good_date, anchor_year, COinS_date = check_date (v.val, k, tCOinS_date); -- go test the date
end
elseif 'year' == k then -- if the parameter is |year= it should hold only a year value
if v.val:match("^[1-9]%d%d%d?%a?$") then -- if |year = 3 or 4 digits only with or without a CITEREF disambiguator
good_date, anchor_year, COinS_date = true, v.val:match("((%d+)%a?)");
end
elseif 'pmc-embargo-date' == k then -- if the parameter is |pmc-embargo-date=
good_date = check_date (v.val, k); -- go test the date
if true == good_date then -- if the date is a valid date
good_date, embargo_date = is_valid_embargo_date (v.val); -- is |pmc-embargo-date= date a single dmy, mdy, or ymd formatted date? yes: returns embargo date; no: returns 9999
end
else -- any other date-holding parameter
good_date = check_date (v.val, k); -- go test the date
end
if false == good_date then -- assemble one error message so we don't add the tracking category multiple times
table.insert (error_list, wrap_style ('parameter', v.name)); -- make parameter name suitable for error message list
end
end
end
return anchor_year, embargo_date; -- and done
end
--[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------
Compare the value provided in |year= with the year value(s) provided in |date=. This function sets a local numeric value:
0 - year value does not match the year value in date
1 - (default) year value matches the year value in date or one of the year values when date contains two years
2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx)
the numeric value in <result> determines the 'output' if any from this function:
0 – adds error message to error_list sequence table
1 – adds maint cat
2 – does nothing
]]
local function year_date_check (year_string, year_origin, date_string, date_origin, error_list)
local year;
local date1;
local date2;
local result = 1; -- result of the test; assume that the test passes
year = year_string:match ('(%d%d%d%d?)');
if date_string:match ('%d%d%d%d%-%d%d%-%d%d') and year_string:match ('%d%d%d%d%a') then --special case where both date and year are required YYYY-MM-DD and YYYYx
date1 = date_string:match ('(%d%d%d%d)');
year = year_string:match ('(%d%d%d%d)');
if year ~= date1 then
result = 0; -- years don't match
else
result = 2; -- years match; but because disambiguated, don't add to maint cat
end
elseif date_string:match ("%d%d%d%d?.-%d%d%d%d?") then -- any of the standard range formats of date with two three- or four-digit years
date1, date2 = date_string:match ("(%d%d%d%d?).-(%d%d%d%d?)");
if year ~= date1 and year ~= date2 then
result = 0;
end
elseif mw.ustring.match(date_string, "%d%d%d%d[%-–]%d%d") then -- YYYY-YY date ranges
local century;
date1, century, date2 = mw.ustring.match(date_string, "((%d%d)%d%d)[%-–]+(%d%d)");
date2 = century..date2; -- convert YY to YYYY
if year ~= date1 and year ~= date2 then
result = 0;
end
elseif date_string:match ("%d%d%d%d?") then -- any of the standard formats of date with one year
date1 = date_string:match ("(%d%d%d%d?)");
if year ~= date1 then
result = 0;
end
else -- should never get here; this function called only when no other date errors
result = 0; -- no recognizable year in date
end
if 0 == result then -- year / date mismatch
table.insert (error_list, substitute (cfg.messages['mismatch'], {year_origin, date_origin})); -- add error message to error_list sequence table
elseif 1 == result then -- redundant year / date
set_message ('maint_date_year'); -- add a maint cat
end
end
--[[--------------------------< R E F O R M A T T E R >--------------------------------------------------------
reformat 'date' into new format specified by format_param if pattern_idx (the current format of 'date') can be
reformatted. Does the grunt work for reformat_dates().
The table re_formats maps pattern_idx (current format) and format_param (desired format) to a table that holds:
format string used by string.format()
identifier letters ('d', 'm', 'y', 'd2', 'm2', 'y2') that serve as indexes into a table t{} that holds captures
from mw.ustring.match() for the various date parts specified by patterns[pattern_idx][1]
Items in patterns{} have the general form:
['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'}, where:
['ymd'] is pattern_idx
patterns['ymd'][1] is the match pattern with captures for mw.ustring.match()
patterns['ymd'][2] is an indicator letter identifying the content of the first capture
patterns['ymd'][3] ... the second capture etc.
when a pattern matches a date, the captures are loaded into table t{} in capture order using the idemtifier
characters as indexes into t{} For the above, a ymd date is in t{} as:
t.y = first capture (year), t.m = second capture (month), t.d = third capture (day)
To reformat, this function is called with the pattern_idx that matches the current format of the date and with
format_param set to the desired format. This function loads table t{} as described and then calls string.format()
with the format string specified by re_format[pattern_idx][format_param][1] using values taken from t{} according
to the capture identifier letters specified by patterns[pattern_idx][format_param][n] where n is 2..
]]
local re_formats = {
['ymd'] = { -- date format is ymd; reformat to:
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['Mdy'] = { -- date format is Mdy; reformat to:
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- for long/short reformatting
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['dMy'] = { -- date format is dMy; reformat to:
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki
},
['Md-dy'] = { -- date format is Md-dy; reformat to:
['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- for long/short reformatting
['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- |df=dmy -> d-dMy
},
['d-dMy'] = { -- date format is d-d>y; reformat to:
['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- |df=mdy -> Md-dy
},
['dM-dMy'] = { -- date format is dM-dMy; reformat to:
['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- for long/short reformatting
['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- |df=mdy -> Md-Mdy
},
['Md-Mdy'] = { -- date format is Md-Mdy; reformat to:
['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- for long/short reformatting
['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- |df=dmy -> dM-dMy
},
['dMy-dMy'] = { -- date format is dMy-dMy; reformat to:
['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- for long/short reformatting
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- |df=mdy -> Mdy-Mdy
},
['Mdy-Mdy'] = { -- date format is Mdy-Mdy; reformat to:
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- for long/short reformatting
['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- |df=dmy -> dMy-dMy
},
['My-My'] = { -- these for long/short reformatting
['any'] = {'%s %s – %s %s', 'm', 'y', 'm2', 'y2'}, -- dmy/mdy agnostic
},
['M-My'] = { -- these for long/short reformatting
['any'] = {'%s–%s %s', 'm', 'm2', 'y'}, -- dmy/mdy agnostic
},
['My'] = { -- these for long/short reformatting
['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic
},
-- ['yMd'] = { -- not supported at en.wiki
-- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy
-- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy
-- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd
-- },
}
local function reformatter (date, pattern_idx, format_param, mon_len)
if not in_array (pattern_idx, {'ymd', 'Mdy', 'Md-dy', 'dMy', 'yMd', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then
return; -- not in this set of date format patterns then not a reformattable date
end
if 'ymd' == format_param and in_array (pattern_idx, {'ymd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then
return; -- ymd date ranges not supported at en.wiki; no point in reformatting ymd to ymd
end
if in_array (pattern_idx, {'My', 'M-My', 'My-My'}) then -- these are not dmy/mdy so can't be 'reformatted' into either
format_param = 'any'; -- so format-agnostic
end
-- yMd is not supported at en.wiki; when yMd is supported at your wiki, uncomment the next line
-- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- these formats not convertable; yMd not supported at en.wiki
if 'yMd' == format_param then -- yMd not supported at en.wiki; when yMd is supported at your wiki, remove or comment-out this line
return; -- not a reformattable date
end
local c1, c2, c3, c4, c5, c6, c7; -- these hold the captures specified in patterns[pattern_idx][1]
c1, c2, c3, c4, c5, c6, c7 = mw.ustring.match (date, patterns[pattern_idx][1]); -- get the captures
local t = { -- table that holds k/v pairs of date parts from the captures and patterns[pattern_idx][2..]
[patterns[pattern_idx][2]] = c1; -- at minimum there is always one capture with a matching indicator letter
[patterns[pattern_idx][3] or 'x'] = c2; -- patterns can have a variable number of captures; each capture requires an indicator letter;
[patterns[pattern_idx][4] or 'x'] = c3; -- where there is no capture, there is no indicator letter so n in patterns[pattern_idx][n] will be nil;
[patterns[pattern_idx][5] or 'x'] = c4; -- the 'x' here spoofs an indicator letter to prevent 'table index is nil' error
[patterns[pattern_idx][6] or 'x'] = c5;
[patterns[pattern_idx][7] or 'x'] = c6;
[patterns[pattern_idx][8] or 'x'] = c7;
};
if t.a then -- if this date has an anchor year capture (all convertable date formats except ymd)
if t.y2 then -- for year range date formats
t.y2 = t.a; -- use the anchor year capture when reassembling the date
else -- here for single date formats (except ymd)
t.y = t.a; -- use the anchor year capture when reassembling the date
end
end
if tonumber(t.m) then -- if raw month is a number (converting from ymd)
if 's' == mon_len then -- if we are to use abbreviated month names
t.m = cfg.date_names['inv_local_short'][tonumber(t.m)]; -- convert it to a month name
else
t.m = cfg.date_names['inv_local_long'][tonumber(t.m)]; -- convert it to a month name
end
t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present
elseif 'ymd' == format_param then -- when converting to ymd
t.y = t.y:gsub ('%a', ''); -- strip CITREF disambiguator if present; anchor year already known so process can proceed; TODO: maint message?
if 1582 > tonumber (t.y) then -- ymd format dates not allowed before 1582
return;
end
t.m = string.format ('%02d', get_month_number (t.m)); -- make sure that month and day are two digits
t.d = string.format ('%02d', t.d);
elseif mon_len then -- if mon_len is set to either 'short' or 'long'
for _, mon in ipairs ({'m', 'm2'}) do -- because there can be two month names, check both
if t[mon] then
t[mon] = get_month_number (t[mon]); -- get the month number for this month (is length agnostic)
if 0 == t[mon] then return; end -- seasons and named dates can't be converted
t[mon] = (('s' == mon_len) and cfg.date_names['inv_local_short'][t[mon]]) or cfg.date_names['inv_local_long'][t[mon]]; -- fetch month name according to length
end
end
end
local new_date = string.format (re_formats[pattern_idx][format_param][1], -- format string
t[re_formats[pattern_idx][format_param][2]], -- named captures from t{}
t[re_formats[pattern_idx][format_param][3]],
t[re_formats[pattern_idx][format_param][4]],
t[re_formats[pattern_idx][format_param][5]],
t[re_formats[pattern_idx][format_param][6]],
t[re_formats[pattern_idx][format_param][7]],
t[re_formats[pattern_idx][format_param][8]]
);
return new_date;
end
--[[-------------------------< R E F O R M A T _ D A T E S >--------------------------------------------------
Reformats existing dates into the format specified by format.
format is one of several manual keywords: dmy, dmy-all, mdy, mdy-all, ymd, ymd-all. The -all version includes
access- and archive-dates; otherwise these dates are not reformatted.
This function allows automatic date formatting. In ~/Configuration, the article source is searched for one of
the {{use xxx dates}} templates. If found, xxx becomes the global date format as xxx-all. If |cs1-dates= in
{{use xxx dates}} has legitimate value then that value determines how cs1|2 dates will be rendered. Legitimate
values for |cs1-dates= are:
l - all dates are rendered with long month names
ls - publication dates use long month names; access-/archive-dates use abbreviated month names
ly - publication dates use long month names; access-/archive-dates rendered in ymd format
s - all dates are rendered with abbreviated (short) month names
sy - publication dates use abbreviated month names; access-/archive-dates rendered in ymd format
y - all dates are rendered in ymd format
the format argument for automatic date formatting will be the format specified by {{use xxx dates}} with the
value supplied by |cs1-dates so one of: xxx-l, xxx-ls, xxx-ly, xxx-s, xxx-sy, xxx-y, or simply xxx (|cs1-dates=
empty, omitted, or invalid) where xxx shall be either of dmy or mdy.
dates are extracted from date_parameters_list, reformatted (if appropriate), and then written back into the
list in the new format. Dates in date_parameters_list are presumed here to be valid (no errors). This function
returns true when a date has been reformatted, false else. Actual reformatting is done by reformatter().
]]
local function reformat_dates (date_parameters_list, format)
local all = false; -- set to false to skip access- and archive-dates
local len_p = 'l'; -- default publication date length shall be long
local len_a = 'l'; -- default access-/archive-date length shall be long
local result = false;
local new_date;
if format:match('%a+%-all') then -- manual df keyword; auto df keyword when length not specified in {{use xxx dates}};
format = format:match('(%a+)%-all'); -- extract the format
all = true; -- all dates are long format dates because this keyword doesn't specify length
elseif format:match('%a+%-[lsy][sy]?') then -- auto df keywords; internal only
all = true; -- auto df applies to all dates; use length specified by capture len_p for all dates
format, len_p, len_a = format:match('(%a+)%-([lsy])([sy]?)'); -- extract the format and length keywords
if 'y' == len_p then -- because allowed by MOS:DATEUNIFY (sort of) range dates and My dates not reformatted
format = 'ymd'; -- override {{use xxx dates}}
elseif (not is_set(len_a)) or (len_p == len_a) then -- no access-/archive-date length specified or same length as publication dates then
len_a = len_p; -- in case len_a not set
end
end -- else only publication dates and they are long
for param_name, param_val in pairs (date_parameters_list) do -- for each date-holding parameter in the list
if is_set (param_val.val) then -- if the parameter has a value
if not (not all and in_array (param_name, {'access-date', 'archive-date'})) then -- skip access- or archive-date unless format is xxx-all; yeah, ugly; TODO: find a better way
for pattern_idx, pattern in pairs (patterns) do
if mw.ustring.match (param_val.val, pattern[1]) then
if all and in_array (param_name, {'access-date', 'archive-date'}) then -- if this date is an access- or archive-date
new_date = reformatter (param_val.val, pattern_idx, (('y' == len_a) and 'ymd') or format, len_a); -- choose ymd or dmy/mdy according to len_a setting
else -- all other dates
new_date = reformatter (param_val.val, pattern_idx, format, len_p);
end
if new_date then -- set when date was reformatted
date_parameters_list[param_name].val = new_date; -- update date in date list
result = true; -- and announce that changes have been made
end
end -- if
end -- for
end -- if
end -- if
end -- for
return result; -- declare boolean result and done
end
--[[--------------------------< D A T E _ H Y P H E N _ T O _ D A S H >----------------------------------------
Loops through the list of date-holding parameters and converts any hyphen to an ndash. Not called if the cs1|2
template has any date errors.
Modifies the date_parameters_list and returns true if hyphens are replaced, else returns false.
]]
local function date_hyphen_to_dash (date_parameters_list)
local result = false;
local n;
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set (param_val.val) and
not mw.ustring.match (param_val.val, patterns.ymd[1]) then -- for those that are not ymd dates (ustring because here digits may not be Western)
param_val.val, n = param_val.val:gsub ('%-', '–'); -- replace any hyphen with ndash
if 0 ~= n then
date_parameters_list[param_name].val = param_val.val; -- update the list
result = true;
end
end
end
return result; -- so we know if any hyphens were replaced
end
--[[-------------------------< D A T E _ N A M E _ X L A T E >------------------------------------------------
Attempts to translate English date names to local-language date names using names supplied by MediaWiki's
date parser function. This is simple name-for-name replacement and may not work for all languages.
if xlat_dig is true, this function will also translate Western (English) digits to the local language's digits.
This will also translate ymd dates.
]]
local function date_name_xlate (date_parameters_list, xlt_dig)
local xlate;
local mode; -- long or short month names
local modified = false;
local date;
local sources_t = {
{cfg.date_names.en.long, cfg.date_names.inv_local_long}, -- for translating long English month names to long local month names
{cfg.date_names.en.short, cfg.date_names.inv_local_short}, -- short month names
{cfg.date_names.en.quarter, cfg.date_names.inv_local_quarter}, -- quarter date names
{cfg.date_names.en.season, cfg.date_names.inv_local_season}, -- season date nam
{cfg.date_names.en.named, cfg.date_names.inv_local_named}, -- named dates
}
local function is_xlateable (month) -- local function to get local date name that replaces existing English-language date name
for _, date_names_t in ipairs (sources_t) do -- for each sequence table in date_names_t
if date_names_t[1][month] then -- if date name is English month (long or short), quarter, season or named and
if date_names_t[2][date_names_t[1][month]] then -- if there is a matching local date name
return date_names_t[2][date_names_t[1][month]]; -- return the local date name
end
end
end
end
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
if is_set(param_val.val) then -- if the parameter has a value
date = param_val.val;
for month in mw.ustring.gmatch (date, '[%a ]+') do -- iterate through all date names in the date (single date or date range)
month = mw.text.trim (month); -- this because quarterly dates contain whitespace
xlate = is_xlateable (month); -- get translate <month>; returns translation or nil
-- if cfg.date_names.en.long[month] then -- long month dates
-- if cfg.date_names.inv_local_long[cfg.date_names.en.long[month]] then
-- xlate = cfg.date_names.inv_local_long[cfg.date_names.en.long[month]];
-- end
---- mode = 'F'; -- English name is long so use long local name
-- elseif cfg.date_names.en.short[month] then -- short month dates
-- if cfg.date_names.inv_local_short[cfg.date_names.en.short[month]] then
-- xlate = cfg.date_names.inv_local_short[cfg.date_names.en.short[month]];
-- end
---- mode = 'M'; -- English name is short so use short local name
-- elseif cfg.date_names.en.quarter[month] then -- quarter dates
-- if cfg.date_names.inv_local_quarter[cfg.date_names.en.quarter[month]] then
-- xlate = cfg.date_names.inv_local_quarter[cfg.date_names.en.quarter[month]];
-- end
-- elseif cfg.date_names.en.season[month] then -- season dates
-- if cfg.date_names.inv_local_season[cfg.date_names.en.season[month]] then
-- xlate = cfg.date_names.inv_local_season[cfg.date_names.en.season[month]];
-- end
-- elseif cfg.date_names.en.named[month] then -- named dates
-- if cfg.date_names.inv_local_named[cfg.date_names.en.named[month]] then
-- xlate = cfg.date_names.inv_local_named[cfg.date_names.en.named[month]];
-- end
-- else
-- xlate=nil; -- not an English month name; could be local language month name
---- mode = nil; -- not an English month name; could be local language month name or an English season name
-- end
if xlate then
-- if mode then -- might be a season
-- xlate = lang_object:formatDate(mode, '1' .. month); -- translate the month name to this local language
date = mw.ustring.gsub (date, month, xlate); -- replace the English with the translation
date_parameters_list[param_name].val = date; -- save the translated date
modified = true;
end
end
if xlt_dig then -- shall we also translate digits?
date = date:gsub ('%d', cfg.date_names.xlate_digits); -- translate digits from Western to 'local digits'
date_parameters_list[param_name].val = date; -- save the translated date
modified = true;
end
end
end
return modified;
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
add_prop_cat = utilities_page_ptr.add_prop_cat ; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
set_message = utilities_page_ptr.set_message;
substitute = utilities_page_ptr.substitute;
wrap_style = utilities_page_ptr.wrap_style;
cfg = cfg_table_ptr; -- import tables from selected Module:Citation/CS1/Configuration
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return { -- return exported functions
dates = dates,
year_date_check = year_date_check,
reformat_dates = reformat_dates,
date_hyphen_to_dash = date_hyphen_to_dash,
date_name_xlate = date_name_xlate,
set_selected_modules = set_selected_modules
}
d0271b200019639fd12f2b6c5e53be0e844e8453
Module:Citation/CS1/Identifiers
828
55
126
125
2022-09-04T15:24:37Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, set_message, select_one, -- functions in Module:Citation/CS1/Utilities
substitute, make_wikilink;
local z; -- table of tables defined in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< P A G E S C O P E V A R I A B L E S >--------------------------------------
declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here
]]
local auto_link_urls = {}; -- holds identifier URLs for those identifiers that can auto-link |title=
--============================<< H E L P E R F U N C T I O N S >>============================================
--[[--------------------------< W I K I D A T A _ A R T I C L E _ N A M E _ G E T >----------------------------
as an aid to internationalizing identifier-label wikilinks, gets identifier article names from Wikidata.
returns :<lang code>:<article title> when <q> has an <article title> for <lang code>; nil else
for identifiers that do not have q, returns nil
for wikis that do not have mw.wikibase installed, returns nil
]]
local function wikidata_article_name_get (q)
if not is_set (q) or (q and not mw.wikibase) then -- when no q number or when a q number but mw.wikibase not installed on this wiki
return nil; -- abandon
end
local wd_article;
local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org
wd_article = mw.wikibase.getSitelink (q, this_wiki_code .. 'wiki'); -- fetch article title from WD; nil when no title available at this wiki
if wd_article then
wd_article = table.concat ({':', this_wiki_code, ':', wd_article}); -- interwiki-style link without brackets if taken from WD; leading colon required
end
return wd_article; -- article title from WD; nil else
end
--[[--------------------------< L I N K _ L A B E L _ M A K E >------------------------------------------------
common function to create identifier link label from handler table or from Wikidata
returns the first available of
1. redirect from local wiki's handler table (if enabled)
2. Wikidata (if there is a Wikidata entry for this identifier in the local wiki's language)
3. label specified in the local wiki's handler table
]]
local function link_label_make (handler)
local wd_article;
if not (cfg.use_identifier_redirects and is_set (handler.redirect)) then -- redirect has priority so if enabled and available don't fetch from Wikidata because expensive
wd_article = wikidata_article_name_get (handler.q); -- if Wikidata has an article title for this wiki, get it;
end
return (cfg.use_identifier_redirects and is_set (handler.redirect) and handler.redirect) or wd_article or handler.link;
end
--[[--------------------------< E X T E R N A L _ L I N K _ I D >----------------------------------------------
Formats a wiki-style external link
]]
local function external_link_id (options)
local url_string = options.id;
local ext_link;
local this_wiki_code = cfg.this_wiki_code; -- Wikipedia subdomain; 'en' for en.wikipedia.org
local wd_article; -- article title from Wikidata
if options.encode == true or options.encode == nil then
url_string = mw.uri.encode (url_string, 'PATH');
end
if options.auto_link and is_set (options.access) then
auto_link_urls[options.auto_link] = table.concat ({options.prefix, url_string, options.suffix});
end
ext_link = mw.ustring.format ('[%s%s%s %s]', options.prefix, url_string, options.suffix or "", mw.text.nowiki (options.id));
if is_set (options.access) then
ext_link = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[options.access].class, cfg.presentation[options.access].title, ext_link}); -- add the free-to-read / paywall lock
end
return table.concat ({
make_wikilink (link_label_make (options), options.label), -- redirect, Wikidata link, or locally specified link (in that order)
options.separator or ' ',
ext_link
});
end
--[[--------------------------< I N T E R N A L _ L I N K _ I D >----------------------------------------------
Formats a wiki-style internal link
TODO: Does not currently need to support options.access, options.encode, auto-linking and COinS (as in external_link_id),
but may be needed in the future for :m:Interwiki_map custom-prefixes like :arxiv:, :bibcode:, :DOI:, :hdl:, :ISSN:,
:JSTOR:, :Openlibrary:, :PMID:, :RFC:.
]]
local function internal_link_id (options)
local id = mw.ustring.gsub (options.id, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9
return table.concat (
{
make_wikilink (link_label_make (options), options.label), -- wiki-link the identifier label
options.separator or ' ', -- add the separator
make_wikilink (
table.concat (
{
options.prefix,
id, -- translated to Western digits
options.suffix or ''
}),
substitute (cfg.presentation['bdi'], {'', mw.text.nowiki (options.id)}) -- bdi tags to prevent Latin script identifiers from being reversed at RTL language wikis
); -- nowiki because MediaWiki still has magic links for ISBN and the like; TODO: is it really required?
});
end
--[[--------------------------< I S _ E M B A R G O E D >------------------------------------------------------
Determines if a PMC identifier's online version is embargoed. Compares the date in |pmc-embargo-date= against
today's date. If embargo date is in the future, returns the content of |pmc-embargo-date=; otherwise, returns
an empty string because the embargo has expired or because |pmc-embargo-date= was not set in this cite.
]]
local function is_embargoed (embargo)
if is_set (embargo) then
local lang = mw.getContentLanguage();
local good1, embargo_date, todays_date;
good1, embargo_date = pcall (lang.formatDate, lang, 'U', embargo);
todays_date = lang:formatDate ('U');
if good1 then -- if embargo date is a good date
if tonumber (embargo_date) >= tonumber (todays_date) then -- is embargo date is in the future?
return embargo; -- still embargoed
else
set_message ('maint_pmc_embargo'); -- embargo has expired; add main cat
return ''; -- unset because embargo has expired
end
end
end
return ''; -- |pmc-embargo-date= not set return empty string
end
--[=[-------------------------< I S _ V A L I D _ B I O R X I V _ D A T E >------------------------------------
returns true if:
2019-12-11T00:00Z <= biorxiv_date < today + 2 days
The dated form of biorxiv identifier has a start date of 2019-12-11. The Unix timestamp for that date is {{#time:U|2019-12-11}} = 1576022400
biorxiv_date is the date provided in those |biorxiv= parameter values that are dated at time 00:00:00 UTC
today is the current date at time 00:00:00 UTC plus 48 hours
if today is 2015-01-01T00:00:00 then
adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser
apparently doesn't understand non-English date month names. This function will always return false when the date
contains a non-English month name because good1 is false after the call to lang_object.formatDate(). To get
around that call this function with date parts and create a YYYY-MM-DD format date.
]=]
local function is_valid_biorxiv_date (y, m, d)
local biorxiv_date = table.concat ({y, m, d}, '-'); -- make ymd date
local good1, good2;
local biorxiv_ts, tomorrow_ts; -- to hold Unix timestamps representing the dates
local lang_object = mw.getContentLanguage();
good1, biorxiv_ts = pcall (lang_object.formatDate, lang_object, 'U', biorxiv_date); -- convert biorxiv_date value to Unix timestamp
good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which tonumber() may not understand
biorxiv_ts = tonumber (biorxiv_ts) or lang_object:parseFormattedNumber (biorxiv_ts); -- convert to numbers for the comparison;
tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts);
else
return false; -- one or both failed to convert to Unix timestamp
end
return ((1576022400 <= biorxiv_ts) and (biorxiv_ts < tomorrow_ts)) -- 2012-12-11T00:00Z <= biorxiv_date < tomorrow's date
end
--[[--------------------------< IS _ V A L I D _ I S X N >-----------------------------------------------------
ISBN-10 and ISSN validator code calculates checksum across all ISBN/ISSN digits including the check digit.
ISBN-13 is checked in isbn().
If the number is valid the result will be 0. Before calling this function, ISBN/ISSN must be checked for length
and stripped of dashes, spaces and other non-ISxN characters.
]]
local function is_valid_isxn (isxn_str, len)
local temp = 0;
isxn_str = { isxn_str:byte(1, len) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39, 'X' → 0x58
len = len + 1; -- adjust to be a loop counter
for i, v in ipairs (isxn_str) do -- loop through all of the bytes and calculate the checksum
if v == string.byte ("X" ) then -- if checkdigit is X (compares the byte value of 'X' which is 0x58)
temp = temp + 10 * (len - i); -- it represents 10 decimal
else
temp = temp + tonumber (string.char (v) )*(len-i);
end
end
return temp % 11 == 0; -- returns true if calculation result is zero
end
--[[--------------------------< IS _ V A L I D _ I S X N _ 1 3 >-----------------------------------------------
ISBN-13 and ISMN validator code calculates checksum across all 13 ISBN/ISMN digits including the check digit.
If the number is valid, the result will be 0. Before calling this function, ISBN-13/ISMN must be checked for length
and stripped of dashes, spaces and other non-ISxN-13 characters.
]]
local function is_valid_isxn_13 (isxn_str)
local temp=0;
isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39
for i, v in ipairs (isxn_str) do
temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); -- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit
end
return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct
end
--[[--------------------------< N O R M A L I Z E _ L C C N >--------------------------------------------------
LCCN normalization (http://www.loc.gov/marc/lccn-namespace.html#normalization)
1. Remove all blanks.
2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash.
3. If there is a hyphen in the string:
a. Remove it.
b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out):
1. All these characters should be digits, and there should be six or less. (not done in this function)
2. If the length of the substring is less than 6, left-fill the substring with zeroes until the length is six.
Returns a normalized LCCN for lccn() to validate. There is no error checking (step 3.b.1) performed in this function.
]]
local function normalize_lccn (lccn)
lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace
if nil ~= string.find (lccn, '/') then
lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it
end
local prefix
local suffix
prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix
if nil ~= suffix then -- if there was a hyphen
suffix = string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6
lccn = prefix..suffix; -- reassemble the LCCN
end
return lccn;
end
--============================<< I D E N T I F I E R F U N C T I O N S >>====================================
--[[--------------------------< A R X I V >--------------------------------------------------------------------
See: http://arxiv.org/help/arxiv_identifier
format and error check arXiv identifier. There are three valid forms of the identifier:
the first form, valid only between date codes 9107 and 0703, is:
arXiv:<archive>.<class>/<date code><number><version>
where:
<archive> is a string of alpha characters - may be hyphenated; no other punctuation
<class> is a string of alpha characters - may be hyphenated; no other punctuation; not the same as |class= parameter which is not supported in this form
<date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01
first digit of YY for this form can only 9 and 0
<number> is a three-digit number
<version> is a 1 or more digit number preceded with a lowercase v; no spaces (undocumented)
the second form, valid from April 2007 through December 2014 is:
arXiv:<date code>.<number><version>
where:
<date code> is four digits in the form YYMM where YY is the last two digits of the four-digit year and MM is the month number January = 01
<number> is a four-digit number
<version> is a 1 or more digit number preceded with a lowercase v; no spaces
the third form, valid from January 2015 is:
arXiv:<date code>.<number><version>
where:
<date code> and <version> are as defined for 0704-1412
<number> is a five-digit number
]]
local function arxiv (options)
local id = options.id;
local class = options.Class; -- TODO: lowercase?
local handler = options.handler;
local year, month, version;
local err_msg = false; -- assume no error message
local text; -- output text
if id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%d$") or id:match("^%a[%a%.%-]+/[90]%d[01]%d%d%d%dv%d+$") then -- test for the 9107-0703 format with or without version
year, month = id:match("^%a[%a%.%-]+/([90]%d)([01]%d)%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((not (90 < year or 8 > year)) or (1 > month or 12 < month)) or -- if invalid year or invalid month
((91 == year and 7 > month) or (7 == year and 3 < month)) then -- if years ok, are starting and ending months ok?
err_msg = true; -- flag for error message
end
elseif id:match("^%d%d[01]%d%.%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%dv%d+$") then -- test for the 0704-1412 with or without version
year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((7 > year) or (14 < year) or (1 > month or 12 < month)) or -- is year invalid or is month invalid? (doesn't test for future years)
((7 == year) and (4 > month)) then -- when year is 07, is month invalid (before April)?
err_msg = true; -- flag for error message
end
elseif id:match("^%d%d[01]%d%.%d%d%d%d%d$") or id:match("^%d%d[01]%d%.%d%d%d%d%dv%d+$") then -- test for the 1501- format with or without version
year, month = id:match("^(%d%d)([01]%d)%.%d%d%d%d%d[v%d]*$");
year = tonumber (year);
month = tonumber (month);
if ((15 > year) or (1 > month or 12 < month)) then -- is year invalid or is month invalid? (doesn't test for future years)
err_msg = true; -- flag for error message
end
else
err_msg = true; -- not a recognized format; flag for error message
end
if err_msg then
options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS
end
local err_msg_t = {};
if err_msg then
set_message ('err_bad_arxiv');
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access});
if is_set (class) then
if id:match ('^%d+') then
text = table.concat ({text, ' [[//arxiv.org/archive/', class, ' ', class, ']]'}); -- external link within square brackets, not wikilink
else
set_message ('err_class_ignored');
end
end
return text;
end
--[[--------------------------< B I B C O D E >--------------------------------------------------------------------
Validates (sort of) and formats a bibcode ID.
Format for bibcodes is specified here: http://adsabs.harvard.edu/abs_doc/help_pages/data.html#bibcodes
But, this: 2015arXiv151206696F is apparently valid so apparently, the only things that really matter are length, 19 characters
and first four digits must be a year. This function makes these tests:
length must be 19 characters
characters in position
1–4 must be digits and must represent a year in the range of 1000 – next year
5 must be a letter
6–8 must be letter, digit, ampersand, or dot (ampersand cannot directly precede a dot; &. )
9–18 must be letter, digit, or dot
19 must be a letter or dot
]]
local function bibcode (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local err_type;
local err_msg = '';
local year;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode,
access = access});
if 19 ~= id:len() then
err_type = cfg.err_msg_supl.length;
else
year = id:match ("^(%d%d%d%d)[%a][%w&%.][%w&%.][%w&%.][%w.]+[%a%.]$");
if not year then -- if nil then no pattern match
err_type = cfg.err_msg_supl.value; -- so value error
else
local next_year = tonumber (os.date ('%Y')) + 1; -- get the current year as a number and add one for next year
year = tonumber (year); -- convert year portion of bibcode to a number
if (1000 > year) or (year > next_year) then
err_type = cfg.err_msg_supl.year; -- year out of bounds
end
if id:find('&%.') then
err_type = cfg.err_msg_supl.journal; -- journal abbreviation must not have '&.' (if it does it's missing a letter)
end
end
end
if is_set (err_type) then -- if there was an error detected
set_message ('err_bad_bibcode', {err_type});
options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< B I O R X I V >-----------------------------------------------------------------
Format bioRxiv ID and do simple error checking. Before 2019-12-11, biorXiv IDs were 10.1101/ followed by exactly
6 digits. After 2019-12-11, biorXiv IDs retained the six-digit identifier but prefixed that with a yyyy.mm.dd.
date and suffixed with an optional version identifier.
The bioRxiv ID is the string of characters:
https://doi.org/10.1101/078733 -> 10.1101/078733
or a date followed by a six-digit number followed by an optional version indicator 'v' and one or more digits:
https://www.biorxiv.org/content/10.1101/2019.12.11.123456v2 -> 10.1101/2019.12.11.123456v2
see https://www.biorxiv.org/about-biorxiv
]]
local function biorxiv (options)
local id = options.id;
local handler = options.handler;
local err_msg = true; -- flag; assume that there will be an error
local patterns = {
'^10.1101/%d%d%d%d%d%d$', -- simple 6-digit identifier (before 2019-12-11)
'^10.1101/(20[1-9]%d)%.([01]%d)%.([0-3]%d)%.%d%d%d%d%d%dv%d+$', -- y.m.d. date + 6-digit identifier + version (after 2019-12-11)
'^10.1101/(20[1-9]%d)%.([01]%d)%.([0-3]%d)%.%d%d%d%d%d%d$', -- y.m.d. date + 6-digit identifier (after 2019-12-11)
}
for _, pattern in ipairs (patterns) do -- spin through the patterns looking for a match
if id:match (pattern) then
local y, m, d = id:match (pattern); -- found a match, attempt to get year, month and date from the identifier
if m then -- m is nil when id is the six-digit form
if not is_valid_biorxiv_date (y, m, d) then -- validate the encoded date; TODO: don't ignore leap-year and actual month lengths ({{#time:}} is a poor date validator)
break; -- date fail; break out early so we don't unset the error message
end
end
err_msg = nil; -- we found a match so unset the error message
break; -- and done
end
end -- err_cat remains set here when no match
if err_msg then
options.coins_list_t['BIORXIV'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_biorxiv'); -- and set the error message
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator,
encode = handler.encode, access = handler.access});
end
--[[--------------------------< C I T E S E E R X >------------------------------------------------------------
CiteSeerX use their own notion of "doi" (not to be confused with the identifiers resolved via doi.org).
The description of the structure of this identifier can be found at Help_talk:Citation_Style_1/Archive_26#CiteSeerX_id_structure
]]
local function citeseerx (options)
local id = options.id;
local handler = options.handler;
local matched;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode,
access = handler.access});
matched = id:match ("^10%.1%.1%.[1-9]%d?%d?%d?%.[1-9]%d?%d?%d?$");
if not matched then
set_message ('err_bad_citeseerx' );
options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< D O I >------------------------------------------------------------------------
Formats a DOI and checks for DOI errors.
DOI names contain two parts: prefix and suffix separated by a forward slash.
Prefix: directory indicator '10.' followed by a registrant code
Suffix: character string of any length chosen by the registrant
This function checks a DOI name for: prefix/suffix. If the DOI name contains spaces or endashes, or, if it ends
with a period or a comma, this function will emit a bad_doi error message.
DOI names are case-insensitive and can incorporate any printable Unicode characters so the test for spaces, endash,
and terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely
if ever used in DOI names.
]]
local function doi (options)
local id = options.id;
local inactive = options.DoiBroken
local access = options.access;
local ignore_invalid = options.accept;
local handler = options.handler;
local err_flag;
local text;
if is_set (inactive) then
local inactive_year = inactive:match("%d%d%d%d") or ''; -- try to get the year portion from the inactive date
local inactive_month, good;
if is_set (inactive_year) then
if 4 < inactive:len() then -- inactive date has more than just a year (could be anything)
local lang_obj = mw.getContentLanguage(); -- get a language object for this wiki
good, inactive_month = pcall (lang_obj.formatDate, lang_obj, 'F', inactive); -- try to get the month name from the inactive date
if not good then
inactive_month = nil; -- something went wrong so make sure this is unset
end
end
else
inactive_year = nil; -- |doi-broken-date= has something but it isn't a date
end
if is_set (inactive_year) and is_set (inactive_month) then
set_message ('maint_doi_inactive_dated', {inactive_year, inactive_month, ' '});
elseif is_set (inactive_year) then
set_message ('maint_doi_inactive_dated', {inactive_year, '', ''});
else
set_message ('maint_doi_inactive');
end
inactive = " (" .. cfg.messages['inactive'] .. ' ' .. inactive .. ')';
end
local registrant = mw.ustring.match (id, '^10%.([^/]+)/[^%s–]-[^%.,]$'); -- registrant set when DOI has the proper basic form
local registrant_err_patterns = { -- these patterns are for code ranges that are not supported
'^[^1-3]%d%d%d%d%.%d%d*$', -- 5 digits with subcode (0xxxx, 40000+); accepts: 10000–39999
'^[^1-5]%d%d%d%d$', -- 5 digits without subcode (0xxxx, 60000+); accepts: 10000–59999
'^[^1-9]%d%d%d%.%d%d*$', -- 4 digits with subcode (0xxx); accepts: 1000–9999
'^[^1-9]%d%d%d$', -- 4 digits without subcode (0xxx); accepts: 1000–9999
'^%d%d%d%d%d%d+', -- 6 or more digits
'^%d%d?%d?$', -- less than 4 digits without subcode (with subcode is legitimate)
'^5555$', -- test registrant will never resolve
'[^%d%.]', -- any character that isn't a digit or a dot
}
if not ignore_invalid then
if registrant then -- when DOI has proper form
for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns
if registrant:match (pattern) then -- to validate registrant codes
err_flag = set_message ('err_bad_doi'); -- when found, mark this DOI as bad
break; -- and done
end
end
else
err_flag = set_message ('err_bad_doi'); -- invalid directory or malformed
end
else
set_message ('maint_doi_ignore');
end
if err_flag then
options.coins_list_t['DOI'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access,
auto_link = not (err_flag or is_set (inactive) or ignore_invalid) and 'doi' or nil -- do not auto-link when |doi-broken-date= has a value or when there is a DOI error or (to play it safe, after all, auto-linking is not essential) when invalid DOIs are ignored
}) .. (inactive or '');
return text;
end
--[[--------------------------< H D L >------------------------------------------------------------------------
Formats an HDL with minor error checking.
HDL names contain two parts: prefix and suffix separated by a forward slash.
Prefix: character string using any character in the UCS-2 character set except '/'
Suffix: character string of any length using any character in the UCS-2 character set chosen by the registrant
This function checks a HDL name for: prefix/suffix. If the HDL name contains spaces, endashes, or, if it ends
with a period or a comma, this function will emit a bad_hdl error message.
HDL names are case-insensitive and can incorporate any printable Unicode characters so the test for endashes and
terminal punctuation may not be technically correct but it appears, that in practice these characters are rarely
if ever used in HDLs.
Query string parameters are named here: http://www.handle.net/proxy_servlet.html. query strings are not displayed
but since '?' is an allowed character in an HDL, '?' followed by one of the query parameters is the only way we
have to detect the query string so that it isn't URL-encoded with the rest of the identifier.
]]
local function hdl (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local query_params = { -- list of known query parameters from http://www.handle.net/proxy_servlet.html
'noredirect',
'ignore_aliases',
'auth',
'cert',
'index',
'type',
'urlappend',
'locatt',
'action',
}
local hdl, suffix, param = id:match ('(.-)(%?(%a+).+)$'); -- look for query string
local found;
if hdl then -- when there are query strings, this is the handle identifier portion
for _, q in ipairs (query_params) do -- spin through the list of query parameters
if param:match ('^' .. q) then -- if the query string begins with one of the parameters
found = true; -- announce a find
break; -- and stop looking
end
end
end
if found then
id = hdl; -- found so replace id with the handle portion; this will be URL-encoded, suffix will not
else
suffix = ''; -- make sure suffix is empty string for concatenation else
end
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, suffix = suffix, separator = handler.separator, encode = handler.encode, access = access})
if nil == id:match("^[^%s–]-/[^%s–]-[^%.,]$") then -- HDL must contain a forward slash, must not contain spaces, endashes, and must not end with period or comma
set_message ('err_bad_hdl' );
options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< I S B N >----------------------------------------------------------------------
Determines whether an ISBN string is valid
]]
local function isbn (options)
local isbn_str = options.id;
local ignore_invalid = options.accept;
local handler = options.handler;
local function return_result (check, err_type) -- local function to handle the various returns
local ISBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect,
prefix = handler.prefix, id = isbn_str, separator = handler.separator});
if ignore_invalid then -- if ignoring ISBN errors
set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error
else -- here when not ignoring
if not check then -- and there is an error
options.coins_list_t['ISBN'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_isbn', err_type); -- set an error message
return ISBN; -- return id text
end
end
return ISBN; -- return id text
end
if nil ~= isbn_str:match ('[^%s-0-9X]') then
return return_result (false, cfg.err_msg_supl.char); -- fail if isbn_str contains anything but digits, hyphens, or the uppercase X
end
local id = isbn_str:gsub ('[%s-]', ''); -- remove hyphens and whitespace
local len = id:len();
if len ~= 10 and len ~= 13 then
return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length
end
if len == 10 then
if id:match ('^%d*X?$') == nil then -- fail if isbn_str has 'X' anywhere but last position
return return_result (false, cfg.err_msg_supl.form);
end
if not is_valid_isxn (id, 10) then -- test isbn-10 for numerical validity
return return_result (false, cfg.err_msg_supl.check); -- fail if isbn-10 is not numerically valid
end
if id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin)
return return_result (false, cfg.err_msg_supl.group); -- fail if isbn-10 begins with 630/1
end
return return_result (true, cfg.err_msg_supl.check); -- pass if isbn-10 is numerically valid
else
if id:match ('^%d+$') == nil then
return return_result (false, cfg.err_msg_supl.char); -- fail if ISBN-13 is not all digits
end
if id:match ('^97[89]%d*$') == nil then
return return_result (false, cfg.err_msg_supl.prefix); -- fail when ISBN-13 does not begin with 978 or 979
end
if id:match ('^9790') then
return return_result (false, cfg.err_msg_supl.group); -- group identifier '0' is reserved to ISMN
end
return return_result (is_valid_isxn_13 (id), cfg.err_msg_supl.check);
end
end
--[[--------------------------< A S I N >----------------------------------------------------------------------
Formats a link to Amazon. Do simple error checking: ASIN must be mix of 10 numeric or uppercase alpha
characters. If a mix, first character must be uppercase alpha; if all numeric, ASINs must be 10-digit
ISBN. If 10-digit ISBN, add a maintenance category so a bot or AWB script can replace |asin= with |isbn=.
Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit.
|asin=630....... and |asin=631....... are (apparently) not a legitimate ISBN though it checksums as one; these
do not cause this function to emit the maint_asin message
This function is positioned here because it calls isbn()
]]
local function asin (options)
local id = options.id;
local domain = options.ASINTLD;
local err_flag;
if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then
err_flag = set_message ('err_bad_asin'); -- ASIN is not a mix of 10 uppercase alpha and numeric characters
else
if id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X)
if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10
if not id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not a valid isbn prefixes but are used by amazon as a numeric identifier
err_flag = set_message ('err_bad_asin'); -- ASIN has ISBN-10 form but begins with something other than 630/1 so probably an isbn
end
elseif not is_set (err_flag) then
err_flag = set_message ('err_bad_asin'); -- ASIN is not ISBN-10
end
elseif not id:match("^%u[%d%u]+$") then
err_flag = set_message ('err_bad_asin'); -- asin doesn't begin with uppercase alpha
end
end
if (not is_set (domain)) or in_array (domain, {'us'}) then -- default: United States
domain = "com";
elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom
domain = "co." .. domain;
elseif in_array (domain, {'z.cn'}) then -- China
domain = "cn";
elseif in_array (domain, {'au', 'br', 'mx', 'sg', 'tr'}) then -- Australia, Brazil, Mexico, Singapore, Turkey
domain = "com." .. domain;
elseif not in_array (domain, {'ae', 'ca', 'cn', 'de', 'es', 'fr', 'in', 'it', 'nl', 'pl', 'sa', 'se', 'co.jp', 'co.uk', 'com', 'com.au', 'com.br', 'com.mx', 'com.sg', 'com.tr'}) then -- Arabic Emirates, Canada, China, Germany, Spain, France, Indonesia, Italy, Netherlands, Poland, Saudi Arabia, Sweden (as of 2021-03 Austria (.at), Liechtenstein (.li) and Switzerland (.ch) still redirect to the German site (.de) with special settings, so don't maintain local ASINs for them)
err_flag = set_message ('err_bad_asin_tld'); -- unsupported asin-tld value
end
local handler = options.handler;
if not is_set (err_flag) then
options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; -- asin for coins
else
options.coins_list_t['ASIN'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix .. domain .. "/dp/",
id = id, encode = handler.encode, separator = handler.separator})
end
--[[--------------------------< I S M N >----------------------------------------------------------------------
Determines whether an ISMN string is valid. Similar to ISBN-13, ISMN is 13 digits beginning 979-0-... and uses the
same check digit calculations. See http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf
section 2, pages 9–12.
ismn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx)
or an identifier registered at info-uri.info (info:)
]]
local function ismn (options)
local id = options.id;
local handler = options.handler;
local text;
local valid_ismn = true;
local id_copy;
id_copy = id; -- save a copy because this testing is destructive
id = id:gsub ('[%s-]', ''); -- remove hyphens and white space
if 13 ~= id:len() or id:match ("^9790%d*$" ) == nil then -- ISMN must be 13 digits and begin with 9790
valid_ismn = false;
else
valid_ismn=is_valid_isxn_13 (id); -- validate ISMN
end
-- text = internal_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- use this (or external version) when there is some place to link to
-- prefix = handler.prefix, id = id_copy, separator = handler.separator, encode = handler.encode})
text = table.concat ( -- because no place to link to yet
{
make_wikilink (link_label_make (handler), handler.label),
handler.separator,
id_copy
});
if false == valid_ismn then
options.coins_list_t['ISMN'] = nil; -- when error, unset so not included in COinS; not really necessary here because ismn not made part of COinS
set_message ('err_bad_ismn'); -- create an error message if the ISMN is invalid
end
return text;
end
--[[--------------------------< I S S N >----------------------------------------------------------------------
Validate and format an ISSN. This code fixes the case where an editor has included an ISSN in the citation but
has separated the two groups of four digits with a space. When that condition occurred, the resulting link looked
like this:
|issn=0819 4327 gives: [http://www.worldcat.org/issn/0819 4327 0819 4327] -- can't have spaces in an external link
This code now prevents that by inserting a hyphen at the ISSN midpoint. It also validates the ISSN for length
and makes sure that the checkdigit agrees with the calculated value. Incorrect length (8 digits), characters
other than 0-9 and X, or checkdigit / calculated value mismatch will all cause a check ISSN error message. The
ISSN is always displayed with a hyphen, even if the ISSN was given as a single group of 8 digits.
]]
local function issn (options)
local id = options.id;
local handler = options.handler;
local ignore_invalid = options.accept;
local issn_copy = id; -- save a copy of unadulterated ISSN; use this version for display if ISSN does not validate
local text;
local valid_issn = true;
id = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace
if 8 ~= id:len() or nil == id:match ("^%d*X?$" ) then -- validate the ISSN: 8 digits long, containing only 0-9 or X in the last position
valid_issn = false; -- wrong length or improper character
else
valid_issn = is_valid_isxn (id, 8); -- validate ISSN
end
if true == valid_issn then
id = string.sub (id, 1, 4 ) .. "-" .. string.sub (id, 5 ); -- if valid, display correctly formatted version
else
id = issn_copy; -- if not valid, show the invalid ISSN with error message
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
if ignore_invalid then
set_message ('maint_issn_ignore');
else
if false == valid_issn then
options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- create an error message if the ISSN is invalid
end
end
return text;
end
--[[--------------------------< J F M >-----------------------------------------------------------------------
A numerical identifier in the form nn.nnnn.nn
]]
local function jfm (options)
local id = options.id;
local handler = options.handler;
local id_num;
id_num = id:match ('^[Jj][Ff][Mm](.*)$'); -- identifier with jfm prefix; extract identifier
if is_set (id_num) then
set_message ('maint_jfm_format');
else -- plain number without JFM prefix
id_num = id; -- if here id does not have prefix
end
if id_num and id_num:match('^%d%d%.%d%d%d%d%.%d%d$') then
id = id_num; -- jfm matches pattern
else
set_message ('err_bad_jfm' ); -- set an error message
options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< J S T O R >--------------------------------------------------------------------
Format a JSTOR with some error checking
]]
local function jstor (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then
set_message ('err_bad_jstor'); -- set an error message
options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
end
--[[--------------------------< L C C N >----------------------------------------------------------------------
Format LCCN link and do simple error checking. LCCN is a character string 8-12 characters long. The length of
the LCCN dictates the character type of the first 1-3 characters; the rightmost eight are always digits.
http://info-uri.info/registry/OAIHandler?verb=GetRecord&metadataPrefix=reg&identifier=info:lccn/
length = 8 then all digits
length = 9 then lccn[1] is lowercase alpha
length = 10 then lccn[1] and lccn[2] are both lowercase alpha or both digits
length = 11 then lccn[1] is lower case alpha, lccn[2] and lccn[3] are both lowercase alpha or both digits
length = 12 then lccn[1] and lccn[2] are both lowercase alpha
]]
local function lccn (options)
local lccn = options.id;
local handler = options.handler;
local err_flag; -- presume that LCCN is valid
local id = lccn; -- local copy of the LCCN
id = normalize_lccn (id); -- get canonical form (no whitespace, hyphens, forward slashes)
local len = id:len(); -- get the length of the LCCN
if 8 == len then
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits)
err_flag = set_message ('err_bad_lccn'); -- set an error message
end
elseif 9 == len then -- LCCN should be adddddddd
if nil == id:match("%l%d%d%d%d%d%d%d%d") then -- does it match our pattern?
err_flag = set_message ('err_bad_lccn'); -- set an error message
end
elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ...
if nil == id:match("^%l%l%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
end
elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd
if not (id:match("^%l%l%l%d%d%d%d%d%d%d%d") or id:match("^%l%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
elseif 12 == len then -- LCCN should be aadddddddddd
if not id:match("^%l%l%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern
err_flag = set_message ('err_bad_lccn'); -- no match, set an error message
end
else
err_flag = set_message ('err_bad_lccn'); -- wrong length, set an error message
end
if not is_set (err_flag) and nil ~= lccn:find ('%s') then
err_flag = set_message ('err_bad_lccn'); -- lccn contains a space, set an error message
end
if is_set (err_flag) then
options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = lccn, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< M R >--------------------------------------------------------------------------
A seven digit number; if not seven digits, zero-fill leading digits to make seven digits.
]]
local function mr (options)
local id = options.id;
local handler = options.handler;
local id_num;
local id_len;
id_num = id:match ('^[Mm][Rr](%d+)$'); -- identifier with mr prefix
if is_set (id_num) then
set_message ('maint_mr_format'); -- add maint cat
else -- plain number without mr prefix
id_num = id:match ('^%d+$'); -- if here id is all digits
end
id_len = id_num and id_num:len() or 0;
if (7 >= id_len) and (0 ~= id_len) then
id = string.rep ('0', 7-id_len) .. id_num; -- zero-fill leading digits
else
set_message ('err_bad_mr'); -- set an error message
options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< O C L C >----------------------------------------------------------------------
Validate and format an OCLC ID. https://www.oclc.org/batchload/controlnumber.en.html {{dead link}}
archived at: https://web.archive.org/web/20161228233804/https://www.oclc.org/batchload/controlnumber.en.html
]]
local function oclc (options)
local id = options.id;
local handler = options.handler;
local number;
if id:match('^ocm%d%d%d%d%d%d%d%d$') then -- ocm prefix and 8 digits; 001 field (12 characters)
number = id:match('ocm(%d+)'); -- get the number
elseif id:match('^ocn%d%d%d%d%d%d%d%d%d$') then -- ocn prefix and 9 digits; 001 field (12 characters)
number = id:match('ocn(%d+)'); -- get the number
elseif id:match('^on%d%d%d%d%d%d%d%d%d%d+$') then -- on prefix and 10 or more digits; 001 field (12 characters)
number = id:match('^on(%d%d%d%d%d%d%d%d%d%d+)$'); -- get the number
elseif id:match('^%(OCoLC%)[1-9]%d*$') then -- (OCoLC) prefix and variable number digits; no leading zeros; 035 field
number = id:match('%(OCoLC%)([1-9]%d*)'); -- get the number
if 9 < number:len() then
number = nil; -- constrain to 1 to 9 digits; change this when OCLC issues 10-digit numbers
end
elseif id:match('^%d+$') then -- no prefix
number = id; -- get the number
if 10 < number:len() then
number = nil; -- constrain to 1 to 10 digits; change this when OCLC issues 11-digit numbers
end
end
if number then -- proper format
id = number; -- exclude prefix, if any, from external link
else
set_message ('err_bad_oclc') -- add an error message if the id is malformed
options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< O P E N L I B R A R Y >--------------------------------------------------------
Formats an OpenLibrary link, and checks for associated errors.
]]
local function openlibrary (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local ident, code = id:gsub('^OL', ''):match("^(%d+([AMW]))$"); -- strip optional OL prefix followed immediately by digits followed by 'A', 'M', or 'W';
local err_flag;
local prefix = { -- these are appended to the handler.prefix according to code
['A']='authors/OL',
['M']='books/OL',
['W']='works/OL',
['X']='OL' -- not a code; spoof when 'code' in id is invalid
};
if not ident then
code = 'X'; -- no code or id completely invalid
ident = id; -- copy id to ident so that we display the flawed identifier
err_flag = set_message ('err_bad_ol');
end
if not is_set (err_flag) then
options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins
else
options.coins_list_t['OL'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix .. prefix[code],
id = ident, separator = handler.separator, encode = handler.encode,
access = access});
end
--[[--------------------------< O S T I >----------------------------------------------------------------------
Format OSTI and do simple error checking. OSTIs are sequential numbers beginning at 1 and counting up. This
code checks the OSTI to see that it contains only digits and is less than test_limit specified in the configuration;
the value in test_limit will need to be updated periodically as more OSTIs are issued.
NB. 1018 is the lowest OSTI number found in the wild (so far) and resolving OK on the OSTI site
]]
local function osti (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
if id:match("[^%d]") then -- if OSTI has anything but digits
set_message ('err_bad_osti'); -- set an error message
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
else -- OSTI is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries
set_message ('err_bad_osti'); -- set an error message
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
end
--[[--------------------------< P M C >------------------------------------------------------------------------
Format a PMC, do simple error checking, and check for embargoed articles.
The embargo parameter takes a date for a value. If the embargo date is in the future the PMC identifier will not
be linked to the article. If the embargo date is today or in the past, or if it is empty or omitted, then the
PMC identifier is linked to the article through the link at cfg.id_handlers['PMC'].prefix.
PMC embargo date testing is done in function is_embargoed () which is called earlier because when the citation
has |pmc=<value> but does not have a |url= then |title= is linked with the PMC link. Function is_embargoed ()
returns the embargo date if the PMC article is still embargoed, otherwise it returns an empty string.
PMCs are sequential numbers beginning at 1 and counting up. This code checks the PMC to see that it contains only digits and is less
than test_limit; the value in local variable test_limit will need to be updated periodically as more PMCs are issued.
]]
local function pmc (options)
local id = options.id;
local embargo = options.Embargo; -- TODO: lowercase?
local handler = options.handler;
local err_flag;
local id_num;
local text;
id_num = id:match ('^[Pp][Mm][Cc](%d+)$'); -- identifier with PMC prefix
if is_set (id_num) then
set_message ('maint_pmc_format');
else -- plain number without PMC prefix
id_num = id:match ('^%d+$'); -- if here id is all digits
end
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMC is outside test limit boundaries
err_flag = set_message ('err_bad_pmc'); -- set an error message
else
id = tostring (id_num); -- make sure id is a string
end
else -- when id format incorrect
err_flag = set_message ('err_bad_pmc'); -- set an error message
end
if is_set (embargo) and is_set (is_embargoed (embargo)) then -- is PMC is still embargoed?
text = table.concat ( -- still embargoed so no external link
{
make_wikilink (link_label_make (handler), handler.label),
handler.separator,
id,
});
else
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- no embargo date or embargo has expired, ok to link to article
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access,
auto_link = not err_flag and 'pmc' or nil -- do not auto-link when PMC has error
});
end
if err_flag then
options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< P M I D >----------------------------------------------------------------------
Format PMID and do simple error checking. PMIDs are sequential numbers beginning at 1 and counting up. This
code checks the PMID to see that it contains only digits and is less than test_limit; the value in local variable
test_limit will need to be updated periodically as more PMIDs are issued.
]]
local function pmid (options)
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if PMID has anything but digits
set_message ('err_bad_pmid'); -- set an error message
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
else -- PMID is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries
set_message ('err_bad_pmid'); -- set an error message
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--[[--------------------------< R F C >------------------------------------------------------------------------
Format RFC and do simple error checking. RFCs are sequential numbers beginning at 1 and counting up. This
code checks the RFC to see that it contains only digits and is less than test_limit specified in the configuration;
the value in test_limit will need to be updated periodically as more RFCs are issued.
An index of all RFCs is here: https://tools.ietf.org/rfc/
]]
local function rfc (options)
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if RFC has anything but digits
set_message ('err_bad_rfc'); -- set an error message
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
else -- RFC is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries
set_message ('err_bad_rfc'); -- set an error message
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
end
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access});
end
--[[--------------------------< S 2 C I D >--------------------------------------------------------------------
Format an S2CID, do simple error checking
S2CIDs are sequential numbers beginning at 1 and counting up. This code checks the S2CID to see that it is only
digits and is less than test_limit; the value in local variable test_limit will need to be updated periodically
as more S2CIDs are issued.
]]
local function s2cid (options)
local id = options.id;
local access = options.access;
local handler = options.handler;
local id_num;
local text;
id_num = id:match ('^[1-9]%d*$'); -- id must be all digits; must not begin with 0; no open access flag
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries
set_message ('err_bad_s2cid'); -- set an error message
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
set_message ('err_bad_s2cid'); -- set an error message
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access});
return text;
end
--[[--------------------------< S B N >------------------------------------------------------------------------
9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits
sbn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx)
or an identifier registered at info-uri.info (info:)
]]
local function sbn (options)
local id = options.id;
local ignore_invalid = options.accept;
local handler = options.handler;
local function return_result (check, err_type) -- local function to handle the various returns
local SBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator});
if not ignore_invalid then -- if not ignoring SBN errors
if not check then
options.coins_list_t['SBN'] = nil; -- when error, unset so not included in COinS; not really necessary here because sbn not made part of COinS
set_message ('err_bad_sbn', {err_type}); -- display an error message
return SBN;
end
else
set_message ('maint_isbn_ignore'); -- add a maint category even when there is no error (ToDo: Possibly switch to separate message for SBNs only)
end
return SBN;
end
if id:match ('[^%s-0-9X]') then
return return_result (false, cfg.err_msg_supl.char); -- fail if SBN contains anything but digits, hyphens, or the uppercase X
end
local ident = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace; they interfere with the rest of the tests
if 9 ~= ident:len() then
return return_result (false, cfg.err_msg_supl.length); -- fail if incorrect length
end
if ident:match ('^%d*X?$') == nil then
return return_result (false, cfg.err_msg_supl.form); -- fail if SBN has 'X' anywhere but last position
end
return return_result (is_valid_isxn ('0' .. ident, 10), cfg.err_msg_supl.check);
end
--[[--------------------------< S S R N >----------------------------------------------------------------------
Format an SSRN, do simple error checking
SSRNs are sequential numbers beginning at 100? and counting up. This code checks the SSRN to see that it is
only digits and is greater than 99 and less than test_limit; the value in local variable test_limit will need
to be updated periodically as more SSRNs are issued.
]]
local function ssrn (options)
local id = options.id;
local handler = options.handler;
local id_num;
local text;
id_num = id:match ('^%d+$'); -- id must be all digits
if is_set (id_num) then -- id_num has a value so test it
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries
set_message ('err_bad_ssrn'); -- set an error message
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
set_message ('err_bad_ssrn'); -- set an error message
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = options.access});
return text;
end
--[[--------------------------< U S E N E T _ I D >------------------------------------------------------------
Validate and format a usenet message id. Simple error checking, looks for 'id-left@id-right' not enclosed in
'<' and/or '>' angle brackets.
]]
local function usenet_id (options)
local id = options.id;
local handler = options.handler;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>'
set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid
options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS
end
return text;
end
--[[--------------------------< Z B L >-----------------------------------------------------------------------
A numerical identifier in the form nnnn.nnnnn - leading zeros in the first quartet optional
format described here: http://emis.mi.sanu.ac.rs/ZMATH/zmath/en/help/search/
temporary format is apparently eight digits. Anything else is an error
]]
local function zbl (options)
local id = options.id;
local handler = options.handler;
if id:match('^%d%d%d%d%d%d%d%d$') then -- is this identifier using temporary format?
set_message ('maint_zbl'); -- yes, add maint cat
elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format?
set_message ('err_bad_zbl'); -- no, set an error message
options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode});
end
--============================<< I N T E R F A C E F U N C T I O N S >>==========================================
--[[--------------------------< E X T R A C T _ I D S >------------------------------------------------------------
Populates ID table from arguments using configuration settings. Loops through cfg.id_handlers and searches args for
any of the parameters listed in each cfg.id_handlers['...'].parameters. If found, adds the parameter and value to
the identifier list. Emits redundant error message if more than one alias exists in args
]]
local function extract_ids (args)
local id_list = {}; -- list of identifiers found in args
for k, v in pairs (cfg.id_handlers) do -- k is uppercase identifier name as index to cfg.id_handlers; e.g. cfg.id_handlers['ISBN'], v is a table
v = select_one (args, v.parameters, 'err_redundant_parameters' ); -- v.parameters is a table of aliases for k; here we pick one from args if present
if is_set (v) then id_list[k] = v; end -- if found in args, add identifier to our list
end
return id_list;
end
--[[--------------------------< E X T R A C T _ I D _ A C C E S S _ L E V E L S >--------------------------------------
Fetches custom id access levels from arguments using configuration settings. Parameters which have a predefined access
level (e.g. arxiv) do not use this function as they are directly rendered as free without using an additional parameter.
returns a table of k/v pairs where k is same as the identifier's key in cfg.id_handlers and v is the assigned (valid) keyword
access-level values must match the case used in cfg.keywords_lists['id-access'] (lowercase unless there is some special reason for something else)
]]
local function extract_id_access_levels (args, id_list)
local id_accesses_list = {};
for k, v in pairs (cfg.id_handlers) do
local access_param = v.custom_access; -- name of identifier's access-level parameter
if is_set (access_param) then
local access_level = args[access_param]; -- get the assigned value if there is one
if is_set (access_level) then
if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required
set_message ('err_invalid_param_val', {access_param, access_level});
access_level = nil; -- invalid so unset
end
if not is_set (id_list[k]) then -- identifier access-level must have a matching identifier
set_message ('err_param_access_requires_param', {k:lower()}); -- parameter name is uppercase in cfg.id_handlers (k); lowercase for error message
end
id_accesses_list[k] = cfg.keywords_xlate[access_level]; -- get translated keyword
end
end
end
return id_accesses_list;
end
--[[--------------------------< B U I L D _ I D _ L I S T >----------------------------------------------------
render the identifiers into a sorted sequence table
<ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value
<options_t> is a table of various k/v option pairs provided in the call to new_build_id_list();
modified by this function and passed to all identifier rendering functions
<access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid)
returns a sequence table of sorted (by hkey - 'handler' key) rendered identifier strings
]]
local function build_id_list (ID_list_coins_t, options_t, access_levels_t)
local ID_list_t = {};
local accept;
local func_map = { --function map points to functions associated with hkey identifier
['ARXIV'] = arxiv,
['ASIN'] = asin,
['BIBCODE'] = bibcode,
['BIORXIV'] = biorxiv,
['CITESEERX'] = citeseerx,
['DOI'] = doi,
['EISSN'] = issn,
['HDL'] = hdl,
['ISBN'] = isbn,
['ISMN'] = ismn,
['ISSN'] = issn,
['JFM'] = jfm,
['JSTOR'] = jstor,
['LCCN'] = lccn,
['MR'] = mr,
['OCLC'] = oclc,
['OL'] = openlibrary,
['OSTI'] = osti,
['PMC'] = pmc,
['PMID'] = pmid,
['RFC'] = rfc,
['S2CID'] = s2cid,
['SBN'] = sbn,
['SSRN'] = ssrn,
['USENETID'] = usenet_id,
['ZBL'] = zbl,
}
for hkey, v in pairs (ID_list_coins_t) do
v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else
-- every function gets the options table with value v and accept boolean
options_t.hkey = hkey; -- ~/Configuration handler key
options_t.id = v; -- add that identifier value to the options table
options_t.accept = accept; -- add the accept boolean flag
options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter
options_t.handler = cfg.id_handlers[hkey];
options_t.coins_list_t = ID_list_coins_t; -- pointer to ID_list_coins_t; for |asin= and |ol=; also to keep erroneous values out of the citation's metadata
options_t.coins_list_t[hkey] = v; -- id value without accept-as-written markup for metadata
if options_t.handler.access and not in_array (options_t.handler.access, cfg.keywords_lists['id-access']) then
error (cfg.messages['unknown_ID_access'] .. options_t.handler.access); -- here when handler access key set to a value not listed in list of allowed id access keywords
end
if func_map[hkey] then
local id_text = func_map[hkey] (options_t); -- call the function to get identifier text and any error message
table.insert (ID_list_t, {hkey, id_text}); -- add identifier text to the output sequence table
else
error (cfg.messages['unknown_ID_key'] .. hkey); -- here when func_map doesn't have a function for hkey
end
end
local function comp (a, b) -- used by following table.sort()
return a[1]:lower() < b[1]:lower(); -- sort by hkey
end
table.sort (ID_list_t, comp); -- sequence table of tables sort
for k, v in ipairs (ID_list_t) do -- convert sequence table of tables to simple sequence table of strings
ID_list_t[k] = v[2]; -- v[2] is the identifier rendering from the call to the various functions in func_map{}
end
return ID_list_t;
end
--[[--------------------------< O P T I O N S _ C H E C K >----------------------------------------------------
check that certain option parameters have their associated identifier parameters with values
<ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value
<ID_support_t> is a sequence table of tables created in citation0() where each subtable has four elements:
[1] is the support parameter's assigned value; empty string if not set
[2] is a text string same as key in cfg.id_handlers
[3] is cfg.error_conditions key used to create error message
[4] is original ID support parameter name used to create error message
returns nothing; on error emits an appropriate error message
]]
local function options_check (ID_list_coins_t, ID_support_t)
for _, v in ipairs (ID_support_t) do
if is_set (v[1]) and not ID_list_coins_t[v[2]] then -- when support parameter has a value but matching identifier parameter is missing or empty
set_message (v[3], (v[4])); -- emit the appropriate error message
end
end
end
--[[--------------------------< I D E N T I F I E R _ L I S T S _ G E T >--------------------------------------
Creates two identifier lists: a k/v table of identifiers and their values to be used locally and for use in the
COinS metadata, and a sequence table of the rendered identifier strings that will be included in the rendered
citation.
]]
local function identifier_lists_get (args_t, options_t, ID_support_t)
local ID_list_coins_t = extract_ids (args_t); -- get a table of identifiers and their values for use locally and for use in COinS
options_check (ID_list_coins_t, ID_support_t); -- ID support parameters must have matching identifier parameters
local ID_access_levels_t = extract_id_access_levels (args_t, ID_list_coins_t); -- get a table of identifier access levels
local ID_list_t = build_id_list (ID_list_coins_t, options_t, ID_access_levels_t); -- get a sequence table of rendered identifier strings
return ID_list_t, ID_list_coins_t; -- return the tables
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from select Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
set_message = utilities_page_ptr.set_message;
select_one = utilities_page_ptr.select_one;
substitute = utilities_page_ptr.substitute;
make_wikilink = utilities_page_ptr.make_wikilink;
z = utilities_page_ptr.z; -- table of tables in Module:Citation/CS1/Utilities
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
auto_link_urls = auto_link_urls, -- table of identifier URLs to be used when auto-linking |title=
identifier_lists_get = identifier_lists_get, -- experiment to replace individual calls to build_id_list(), extract_ids, extract_id_access_levels
is_embargoed = is_embargoed;
set_selected_modules = set_selected_modules;
}
0f40bcba575710f5da9e7d29a8305288fbb30ac4
Module:Citation/CS1/COinS
828
56
128
127
2022-09-04T15:24:37Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup; -- functions in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< M A K E _ C O I N S _ T I T L E >----------------------------------------------
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn't corrupted with strings
of %27%27...
]]
local function make_coins_title (title, script)
title = has_accept_as_written (title);
if is_set (title) then
title = strip_apostrophe_markup (title); -- strip any apostrophe markup
else
title = ''; -- if not set, make sure title is an empty string
end
if is_set (script) then
script = script:gsub ('^%l%l%s*:%s*', ''); -- remove language prefix if present (script value may now be empty string)
script = strip_apostrophe_markup (script); -- strip any apostrophe markup
else
script = ''; -- if not set, make sure script is an empty string
end
if is_set (title) and is_set (script) then
script = ' ' .. script; -- add a space before we concatenate
end
return title .. script; -- return the concatenation
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of Lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other Lua magic pattern characters
return argument;
end
--[[--------------------------< G E T _ C O I N S _ P A G E S >------------------------------------------------
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.
]]
local function get_coins_pages (pages)
local pattern;
if not is_set (pages) then return pages; end -- if no page numbers then we're done
while true do
pattern = pages:match("%[(%w*:?//[^ ]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the URL and following space(s): "[url "
if nil == pattern then break; end -- no more URLs
pattern = escape_lua_magic_chars (pattern); -- pattern is not a literal string; escape Lua's magic pattern characters
pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible
end
pages = pages:gsub("[%[%]]", ""); -- remove the brackets
pages = pages:gsub("–", "-" ); -- replace endashes with hyphens
pages = pages:gsub("&%w+;", "-" ); -- and replace HTML entities (– etc.) with hyphens; do we need to replace numerical entities like   and the like?
return pages;
end
--[=[-------------------------< C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R >------------------
There are three options for math markup rendering that depend on the editor's math preference settings. These
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are
PNG images
TeX source
MathML with SVG or PNG fallback
All three are heavy with HTML and CSS which doesn't belong in the metadata.
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings
of the last editor to save the page.
This function gets the rendered form of an equation according to the editor's preference before the page is saved. It
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial
value. To replace multipe equations it is necessary to call this function from within a loop.
]=]
local function coins_replace_math_stripmarker (value)
local stripmarker = cfg.stripmarkers['math'];
local rendering = value:match (stripmarker); -- is there a math stripmarker
if not rendering then -- when value doesn't have a math stripmarker, abandon this test
return false, value;
end
rendering = mw.text.unstripNoWiki (rendering); -- convert stripmarker into rendered value (or nil? ''? when math render error)
if rendering:match ('alt="[^"]+"') then -- if PNG math option
rendering = rendering:match ('alt="([^"]+)"'); -- extract just the math text
elseif rendering:match ('$%s+.+%s+%$') then -- if TeX math option; $ is legit character that is escapes as \$
rendering = rendering:match ('$%s+(.+)%s+%$') -- extract just the math text
elseif rendering:match ('<annotation[^>]+>.+</annotation>') then -- if MathML math option
rendering = rendering:match ('<annotation[^>]+>(.+)</annotation>') -- extract just the math text
else
return false, value; -- had math stripmarker but not one of the three defined forms
end
return true, value:gsub (stripmarker, rendering, 1);
end
--[[--------------------------< C O I N S _ C L E A N U P >----------------------------------------------------
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.
2015-12-10: there is a bug in mw.text.unstripNoWiki (). It replaces math stripmarkers with the appropriate content
when it shouldn't. See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible
characters table?
]]
local function coins_cleanup (value)
local replaced = true; -- default state to get the do loop running
while replaced do -- loop until all math stripmarkers replaced
replaced, value = coins_replace_math_stripmarker (value); -- replace math stripmarker with text representation of the equation
end
value = value:gsub (cfg.stripmarkers['math'], "MATH RENDER ERROR"); -- one or more couldn't be replaced; insert vague error message
value = mw.text.unstripNoWiki (value); -- replace nowiki stripmarkers with their content
value = value:gsub ('<span class="nowrap" style="padding%-left:0%.1em;">'(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s
value = value:gsub (' ', ' '); -- replace entity with plain space
value = value:gsub ('\226\128\138', ' '); -- replace hair space with plain space
if not mw.ustring.find (value, cfg.indic_script) then -- don't remove zero-width joiner characters from indic script
value = value:gsub ('‍', ''); -- remove ‍ entities
value = mw.ustring.gsub (value, '[\226\128\141\226\128\139\194\173]', ''); -- remove zero-width joiner, zero-width space, soft hyphen
end
value = value:gsub ('[\009\010\013 ]+', ' '); -- replace horizontal tab, line feed, carriage return with plain space
return value;
end
--[[--------------------------< C O I N S >--------------------------------------------------------------------
COinS metadata (see <http://ocoins.info/>) allows automated tools to parse the citation information.
]]
local function COinS(data, class)
if 'table' ~= type(data) or nil == next(data) then
return '';
end
for k, v in pairs (data) do -- spin through all of the metadata parameter values
if 'ID_list' ~= k and 'Authors' ~= k then -- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)
data[k] = coins_cleanup (v);
end
end
local ctx_ver = "Z39.88-2004";
-- treat table strictly as an array with only set values.
local OCinSoutput = setmetatable( {}, {
__newindex = function(self, key, value)
if is_set(value) then
rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( remove_wiki_link( value ) ) } );
end
end
});
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'ssrn', 'journal', 'news', 'magazine'}) or (in_array (class, {'conference', 'interview', 'map', 'press release', 'web'}) and is_set(data.Periodical)) or
('citation' == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; -- journal metadata identifier
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'ssrn'}) then -- set genre according to the type of citation template we are rendering
OCinSoutput["rft.genre"] = "preprint"; -- cite arxiv, cite biorxiv, cite citeseerx, cite ssrn
elseif 'conference' == class then
OCinSoutput["rft.genre"] = "conference"; -- cite conference (when Periodical set)
elseif 'web' == class then
OCinSoutput["rft.genre"] = "unknown"; -- cite web (when Periodical set)
else
OCinSoutput["rft.genre"] = "article"; -- journal and other 'periodical' articles
end
OCinSoutput["rft.jtitle"] = data.Periodical; -- journal only
OCinSoutput["rft.atitle"] = data.Title; -- 'periodical' article titles
-- these used only for periodicals
OCinSoutput["rft.ssn"] = data.Season; -- keywords: winter, spring, summer, fall
OCinSoutput["rft.quarter"] = data.Quarter; -- single digits 1->first quarter, etc.
OCinSoutput["rft.chron"] = data.Chron; -- free-form date components
OCinSoutput["rft.volume"] = data.Volume; -- does not apply to books
OCinSoutput["rft.issue"] = data.Issue;
OCinSoutput["rft.pages"] = data.Pages; -- also used in book metadata
elseif 'thesis' ~= class then -- all others except cite thesis are treated as 'book' metadata; genre distinguishes
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; -- book metadata identifier
if 'report' == class or 'techreport' == class then -- cite report and cite techreport
OCinSoutput["rft.genre"] = "report";
elseif 'conference' == class then -- cite conference when Periodical not set
OCinSoutput["rft.genre"] = "conference";
OCinSoutput["rft.atitle"] = data.Chapter; -- conference paper as chapter in proceedings (book)
elseif in_array (class, {'book', 'citation', 'encyclopaedia', 'interview', 'map'}) then
if is_set (data.Chapter) then
OCinSoutput["rft.genre"] = "bookitem";
OCinSoutput["rft.atitle"] = data.Chapter; -- book chapter, encyclopedia article, interview in a book, or map title
else
if 'map' == class or 'interview' == class then
OCinSoutput["rft.genre"] = 'unknown'; -- standalone map or interview
else
OCinSoutput["rft.genre"] = 'book'; -- book and encyclopedia
end
end
else -- {'audio-visual', 'AV-media-notes', 'DVD-notes', 'episode', 'interview', 'mailinglist', 'map', 'newsgroup', 'podcast', 'press release', 'serial', 'sign', 'speech', 'web'}
OCinSoutput["rft.genre"] = "unknown";
end
OCinSoutput["rft.btitle"] = data.Title; -- book only
OCinSoutput["rft.place"] = data.PublicationPlace; -- book only
OCinSoutput["rft.series"] = data.Series; -- book only
OCinSoutput["rft.pages"] = data.Pages; -- book, journal
OCinSoutput["rft.edition"] = data.Edition; -- book only
OCinSoutput["rft.pub"] = data.PublisherName; -- book and dissertation
else -- cite thesis
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:dissertation"; -- dissertation metadata identifier
OCinSoutput["rft.title"] = data.Title; -- dissertation (also patent but that is not yet supported)
OCinSoutput["rft.degree"] = data.Degree; -- dissertation only
OCinSoutput['rft.inst'] = data.PublisherName; -- book and dissertation
end
-- NB. Not currently supported are "info:ofi/fmt:kev:mtx:patent", "info:ofi/fmt:kev:mtx:dc", "info:ofi/fmt:kev:mtx:sch_svc", "info:ofi/fmt:kev:mtx:ctx"
-- and now common parameters (as much as possible)
OCinSoutput["rft.date"] = data.Date; -- book, journal, dissertation
for k, v in pairs( data.ID_list ) do -- what to do about these? For now assume that they are common to all?
if k == 'ISBN' then v = v:gsub( "[^-0-9X]", "" ); end
local id = cfg.id_handlers[k].COinS;
if string.sub( id or "", 1, 4 ) == 'info' then -- for ids that are in the info:registry
OCinSoutput["rft_id"] = table.concat{ id, "/", v };
elseif string.sub (id or "", 1, 3 ) == 'rft' then -- for isbn, issn, eissn, etc. that have defined COinS keywords
OCinSoutput[ id ] = v;
elseif 'url' == id then -- for urls that are assembled in ~/Identifiers; |asin= and |ol=
OCinSoutput["rft_id"] = table.concat ({data.ID_list[k], "#id-name=", cfg.id_handlers[k].label});
elseif id then -- when cfg.id_handlers[k].COinS is not nil so urls created here
OCinSoutput["rft_id"] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or '', "#id-name=", cfg.id_handlers[k].label }; -- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)
end
end
local last, first;
for k, v in ipairs( data.Authors ) do
last, first = coins_cleanup (v.last), coins_cleanup (v.first or ''); -- replace any nowiki stripmarkers, non-printing or invisible characters
if k == 1 then -- for the first author name only
if is_set(last) and is_set(first) then -- set these COinS values if |first= and |last= specify the first author name
OCinSoutput["rft.aulast"] = last; -- book, journal, dissertation
OCinSoutput["rft.aufirst"] = first; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation -- otherwise use this form for the first name
end
else -- for all other authors
if is_set(last) and is_set(first) then
OCinSoutput["rft.au"] = table.concat{ last, ", ", first }; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation
end
-- TODO: At present we do not report "et al.". Add anything special if this condition applies?
end
end
OCinSoutput.rft_id = data.URL;
OCinSoutput.rfr_id = table.concat{ "info:sid/", mw.site.server:match( "[^/]*$" ), ":", data.RawPage };
-- TODO: Add optional extra info:
-- rfr_dat=#REVISION<version> (referrer private data)
-- ctx_id=<data.RawPage>#<ref> (identifier for the context object)
-- ctx_tim=<ts> (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)
-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)
OCinSoutput = setmetatable( OCinSoutput, nil );
-- sort with version string always first, and combine.
-- table.sort( OCinSoutput );
table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"
return table.concat(OCinSoutput, "&");
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
remove_wiki_link = utilities_page_ptr.remove_wiki_link;
strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
make_coins_title = make_coins_title,
get_coins_pages = get_coins_pages,
COinS = COinS,
set_selected_modules = set_selected_modules,
}
54a5c6fce3535cf48f207524439635ed96505a13
Module:Citation/CS1/styles.css
828
57
130
129
2022-09-04T15:24:38Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* Protection icon
the following line controls the page-protection icon in the upper right corner
it must remain within this comment
{{sandbox other||{{pp-template}}}}
*/
/* Overrides
Some wikis do not override user agent default styles for HTML <cite> and <q>,
unlike en.wp. On en.wp, keep these the same as [[MediaWiki:Common.css]].
The word-wrap and :target styles were moved here from Common.css.
On en.wp, keep these the same as [[Template:Citation/styles.css]].
*/
cite.citation {
font-style: inherit; /* Remove italics for <cite> */
/* Break long urls, etc., rather than overflowing box */
word-wrap: break-word;
}
.citation q {
quotes: '"' '"' "'" "'"; /* Straight quote marks for <q> */
}
/* Highlight linked elements (such as clicked references) in blue */
.citation:target {
/* ignore the linter - all browsers of interest implement this */
background-color: rgba(0, 127, 255, 0.133);
}
/* ID and URL access
Both core and Common.css have selector .mw-parser-output a[href$=".pdf"].external
for PDF pages. All TemplateStyles pages are hoisted to .mw-parser-output. We need
to have specificity equal to a[href$=".pdf"].external for locks to override PDF icon.
That's essentially 2 classes and 1 element.
the .id-lock-... selectors are for use by non-citation templates like
{{Catalog lookup link}} which do not have to handle PDF links
*/
.id-lock-free a,
.citation .cs1-lock-free a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/6/65/Lock-green.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-limited a,
.id-lock-registration a,
.citation .cs1-lock-limited a,
.citation .cs1-lock-registration a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/d/d6/Lock-gray-alt-2.svg)
right 0.1em center/9px no-repeat;
}
.id-lock-subscription a,
.citation .cs1-lock-subscription a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/a/aa/Lock-red-alt-2.svg)
right 0.1em center/9px no-repeat;
}
/* Wikisource
Wikisource icon when |chapter= or |title= is wikilinked to Wikisource
as in cite wikisource
*/
.cs1-ws-icon a {
background: linear-gradient(transparent, transparent),
url(//upload.wikimedia.org/wikipedia/commons/4/4c/Wikisource-logo.svg)
right 0.1em center/12px no-repeat;
}
/* Errors and maintenance */
.cs1-code {
/* <code>...</code> style override: mediawiki's css definition is specified here:
https://git.wikimedia.org/blob/mediawiki%2Fcore.git/
69cd73811f7aadd093050dbf20ed70ef0b42a713/skins%2Fcommon%2FcommonElements.css#L199
*/
color: inherit;
background: inherit;
border: none;
padding: inherit;
}
.cs1-hidden-error {
display: none;
color: #d33;
}
.cs1-visible-error {
color: #d33;
}
.cs1-maint {
display: none;
color: #3a3;
margin-left: 0.3em;
}
/* Small text size
Set small text size in one place. 0.95 (here) * 0.9 (from references list) is
~0.85, which is the lower bound for size for accessibility. Old styling for this
was just 0.85. We could write the rule so that when this template is inside
references/reflist, only then does it multiply by 0.95; else multiply by 0.85 */
.cs1-format {
font-size: 95%;
}
/* kerning */
.cs1-kern-left {
padding-left: 0.2em;
}
.cs1-kern-right {
padding-right: 0.2em;
}
/* selflinks – avoid bold font style when cs1|2 template links to the current page */
.citation .mw-selflink {
font-weight: inherit;
}
016143e761e7a41b22296023b6119ee97303dabb
Template:Pagetype
10
58
132
131
2022-09-04T15:24:39Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:pagetype|main}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
b8e6aa66678cd57877ea2c607372a45070f030a7
Module:Pagetype
828
59
134
133
2022-09-04T15:24:39Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- PAGETYPE --
-- --
-- This is a meta-module intended to replace {{pagetype}} and similar --
-- templates. It automatically detects namespaces, and allows for a --
-- great deal of customisation. It can easily be ported to other --
-- wikis by changing the values in the [[Module:Pagetype/config]]. --
-- --
--------------------------------------------------------------------------------
-- Load config.
local cfg = mw.loadData('Module:Pagetype/config')
-- Load required modules.
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local nsDetectModule = require('Module:Namespace detect')
local nsDetect = nsDetectModule._main
local getParamMappings = nsDetectModule.getParamMappings
local getPageObject = nsDetectModule.getPageObject
local p = {}
local function shallowCopy(t)
-- Makes a shallow copy of a table.
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
local function checkPagetypeInput(namespace, val)
-- Checks to see whether we need the default value for the given namespace,
-- and if so gets it from the pagetypes table.
-- The yesno function returns true/false for "yes", "no", etc., and returns
-- val for other input.
local ret = yesno(val, val)
if ret and type(ret) ~= 'string' then
ret = cfg.pagetypes[namespace]
end
return ret
end
local function getPagetypeFromClass(class, param, aliasTable, default)
-- Gets the pagetype from a class specified from the first positional
-- parameter.
param = yesno(param, param)
if param ~= false then -- No check if specifically disallowed.
for _, alias in ipairs(aliasTable) do
if class == alias then
if type(param) == 'string' then
return param
else
return default
end
end
end
end
end
local function getNsDetectValue(args)
-- Builds the arguments to pass to [[Module:Namespace detect]] and returns
-- the result.
-- Get the default values.
local ndArgs = {}
local defaultns = args[cfg.defaultns]
if defaultns == cfg.defaultnsAll then
ndArgs = shallowCopy(cfg.pagetypes)
else
local defaultnsArray
if defaultns == cfg.defaultnsExtended then
defaultnsArray = cfg.extendedNamespaces
elseif defaultns == cfg.defaultnsNone then
defaultnsArray = {}
else
defaultnsArray = cfg.defaultNamespaces
end
for _, namespace in ipairs(defaultnsArray) do
ndArgs[namespace] = cfg.pagetypes[namespace]
end
end
--[[
-- Add custom values passed in from the arguments. These overwrite the
-- defaults. The possible argument names are fetched from
-- Module:Namespace detect automatically in case new namespaces are
-- added. Although we accept namespace aliases as parameters, we only pass
-- the local namespace name as a parameter to Module:Namespace detect.
-- This means that the "image" parameter can overwrite defaults for the
-- File: namespace, which wouldn't work if we passed the parameters through
-- separately.
--]]
local mappings = getParamMappings()
for ns, paramAliases in pairs(mappings) do
-- Copy the aliases table, as # doesn't work with tables returned from
-- mw.loadData.
paramAliases = shallowCopy(paramAliases)
local paramName = paramAliases[1]
-- Iterate backwards along the array so that any values for the local
-- namespace names overwrite those for namespace aliases.
for i = #paramAliases, 1, -1 do
local paramAlias = paramAliases[i]
local ndArg = checkPagetypeInput(paramAlias, args[paramAlias])
if ndArg == false then
-- If any arguments are false, convert them to nil to protect
-- against breakage by future changes to
-- [[Module:Namespace detect]].
ndArgs[paramName] = nil
elseif ndArg then
ndArgs[paramName] = ndArg
end
end
end
-- Check for disambiguation-class and N/A-class pages in mainspace.
if ndArgs.main then
local class = args[1]
if type(class) == 'string' then
-- Put in lower case so e.g. "Dab" and "dab" will both match.
class = mw.ustring.lower(class)
end
local dab = getPagetypeFromClass(
class,
args[cfg.dab],
cfg.dabAliases,
cfg.dabDefault
)
if dab then
ndArgs.main = dab
else
local na = getPagetypeFromClass(
class,
args[cfg.na],
cfg.naAliases,
cfg.naDefault
)
if na then
ndArgs.main = na
end
end
end
-- If there is no talk value specified, use the corresponding subject
-- namespace for talk pages.
if not ndArgs.talk then
ndArgs.subjectns = true
end
-- Add the fallback value. This can also be customised, but it cannot be
-- disabled.
local other = args[cfg.other]
-- We will ignore true/false/nil results from yesno here, but using it
-- anyway for consistency.
other = yesno(other, other)
if type(other) == 'string' then
ndArgs.other = other
else
ndArgs.other = cfg.otherDefault
end
-- Allow custom page values.
ndArgs.page = args.page
return nsDetect(ndArgs)
end
local function detectRedirects(args)
local redirect = args[cfg.redirect]
-- The yesno function returns true/false for "yes", "no", etc., and returns
-- redirect for other input.
redirect = yesno(redirect, redirect)
if redirect == false then
-- Detect redirects unless they have been explicitly disallowed with
-- "redirect=no" or similar.
return
end
local pageObject = getPageObject(args.page)
-- If we are using subject namespaces elsewhere, do so here as well.
if pageObject
and not yesno(args.talk, true)
and args[cfg.defaultns] ~= cfg.defaultnsAll
then
pageObject = getPageObject(
pageObject.subjectNsText .. ':' .. pageObject.text
)
end
-- Allow custom values for redirects.
if pageObject and pageObject.isRedirect then
if type(redirect) == 'string' then
return redirect
else
return cfg.redirectDefault
end
end
end
function p._main(args)
local redirect = detectRedirects(args)
local pagetype = ""
if redirect then
pagetype = redirect
else
pagetype = getNsDetectValue(args)
end
if yesno(args.plural, false) then
if cfg.irregularPlurals[pagetype] then
pagetype = cfg.irregularPlurals[pagetype]
else
pagetype = pagetype .. cfg.plural -- often 's'
end
end
if yesno(args.caps, false) then
pagetype = mw.ustring.upper(mw.ustring.sub(pagetype, 1, 1)) ..
mw.ustring.sub(pagetype, 2)
end
return pagetype
end
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
return p
210524e0c60e3354325aea88c508e94423ad228d
Module:Pagetype/config
828
60
136
135
2022-09-04T15:24:40Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Pagetype configuration data --
-- This page holds localisation and configuration data for Module:Pagetype. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
-- This table holds the values to use for "main=true", "user=true", etc. Keys to
-- this table should be namespace parameters that can be used with
-- [[Module:Namespace detect]].
cfg.pagetypes = {
['main'] = 'article',
['user'] = 'user page',
['project'] = 'project page',
['wikipedia'] = 'project page',
['wp'] = 'project page',
['file'] = 'file',
['image'] = 'file',
['mediawiki'] = 'interface page',
['template'] = 'template',
['help'] = 'help page',
['category'] = 'category',
['portal'] = 'portal',
['draft'] = 'draft',
['timedtext'] = 'Timed Text page',
['module'] = 'module',
['topic'] = 'topic',
['gadget'] = 'gadget',
['gadget definition'] = 'gadget definition',
['talk'] = 'talk page',
['special'] = 'special page',
['media'] = 'file',
}
-- This table holds the names of the namespaces to be looked up from
-- cfg.pagetypes by default.
cfg.defaultNamespaces = {
'main',
'file',
'template',
'category',
'module'
}
-- This table holds the names of the namespaces to be looked up from
-- cfg.pagetypes if cfg.defaultnsExtended is set.
cfg.extendedNamespaces = {
'main',
'user',
'project',
'file',
'mediawiki',
'template',
'category',
'help',
'portal',
'module',
'draft'
}
-- The parameter name to set which default namespace values to be looked up from
-- cfg.pagetypes.
cfg.defaultns = 'defaultns'
-- The value of cfg.defaultns to set all namespaces, including talk.
cfg.defaultnsAll = 'all'
-- The value of cfg.defaultns to set the namespaces listed in
-- cfg.extendedNamespaces
cfg.defaultnsExtended = 'extended'
-- The value of cfg.defaultns to set no default namespaces.
cfg.defaultnsNone = 'none'
-- The parameter name to use for disambiguation pages page.
cfg.dab = 'dab'
-- This table holds the different possible aliases for disambiguation-class
-- pages. These should be lower-case.
cfg.dabAliases = {
'disambiguation',
'disambig',
'disamb',
'dab'
}
-- The default value for disambiguation pages.
cfg.dabDefault = 'page'
-- The parameter name to use for N/A-class page.
cfg.na = 'na'
-- This table holds the different possible aliases for N/A-class pages. These
-- should be lower-case.
cfg.naAliases = {'na', 'n/a'}
-- The default value for N/A-class pages.
cfg.naDefault = 'page'
-- The parameter name to use for redirects.
cfg.redirect = 'redirect'
-- The default value to use for redirects.
cfg.redirectDefault = 'redirect'
-- The parameter name for undefined namespaces.
cfg.other = 'other'
-- The value used if the module detects an undefined namespace.
cfg.otherDefault = 'page'
-- The usual suffix denoting a plural.
cfg.plural = 's'
-- This table holds plurals not formed by a simple suffix.
cfg.irregularPlurals = {
["category"] = "categories"
}
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line
e2eb36d6c43611a422bae37947ebeb04b695dcba
Module:Namespace detect
828
61
138
137
2022-09-04T15:24:41Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[
--------------------------------------------------------------------------------
-- --
-- NAMESPACE DETECT --
-- --
-- This module implements the {{namespace detect}} template in Lua, with a --
-- few improvements: all namespaces and all namespace aliases are supported, --
-- and namespace names are detected automatically for the local wiki. The --
-- module can also use the corresponding subject namespace value if it is --
-- used on a talk page. Parameter names can be configured for different wikis --
-- by altering the values in the "cfg" table in --
-- Module:Namespace detect/config. --
-- --
--------------------------------------------------------------------------------
--]]
local data = mw.loadData('Module:Namespace detect/data')
local argKeys = data.argKeys
local cfg = data.cfg
local mappings = data.mappings
local yesno = require('Module:Yesno')
local mArguments -- Lazily initialise Module:Arguments
local mTableTools -- Lazily initilalise Module:TableTools
local ustringLower = mw.ustring.lower
local p = {}
local function fetchValue(t1, t2)
-- Fetches a value from the table t1 for the first key in array t2 where
-- a non-nil value of t1 exists.
for i, key in ipairs(t2) do
local value = t1[key]
if value ~= nil then
return value
end
end
return nil
end
local function equalsArrayValue(t, value)
-- Returns true if value equals a value in the array t. Otherwise
-- returns false.
for i, arrayValue in ipairs(t) do
if value == arrayValue then
return true
end
end
return false
end
function p.getPageObject(page)
-- Get the page object, passing the function through pcall in case of
-- errors, e.g. being over the expensive function count limit.
if page then
local success, pageObject = pcall(mw.title.new, page)
if success then
return pageObject
else
return nil
end
else
return mw.title.getCurrentTitle()
end
end
-- Provided for backward compatibility with other modules
function p.getParamMappings()
return mappings
end
local function getNamespace(args)
-- This function gets the namespace name from the page object.
local page = fetchValue(args, argKeys.demopage)
if page == '' then
page = nil
end
local demospace = fetchValue(args, argKeys.demospace)
if demospace == '' then
demospace = nil
end
local subjectns = fetchValue(args, argKeys.subjectns)
local ret
if demospace then
-- Handle "demospace = main" properly.
if equalsArrayValue(argKeys.main, ustringLower(demospace)) then
ret = mw.site.namespaces[0].name
else
ret = demospace
end
else
local pageObject = p.getPageObject(page)
if pageObject then
if pageObject.isTalkPage then
-- Get the subject namespace if the option is set,
-- otherwise use "talk".
if yesno(subjectns) then
ret = mw.site.namespaces[pageObject.namespace].subject.name
else
ret = 'talk'
end
else
ret = pageObject.nsText
end
else
return nil -- return nil if the page object doesn't exist.
end
end
ret = ret:gsub('_', ' ')
return ustringLower(ret)
end
function p._main(args)
-- Check the parameters stored in the mappings table for any matches.
local namespace = getNamespace(args) or 'other' -- "other" avoids nil table keys
local params = mappings[namespace] or {}
local ret = fetchValue(args, params)
--[[
-- If there were no matches, return parameters for other namespaces.
-- This happens if there was no text specified for the namespace that
-- was detected or if the demospace parameter is not a valid
-- namespace. Note that the parameter for the detected namespace must be
-- completely absent for this to happen, not merely blank.
--]]
if ret == nil then
ret = fetchValue(args, argKeys.other)
end
return ret
end
function p.main(frame)
mArguments = require('Module:Arguments')
local args = mArguments.getArgs(frame, {removeBlanks = false})
local ret = p._main(args)
return ret or ''
end
function p.table(frame)
--[[
-- Create a wikitable of all subject namespace parameters, for
-- documentation purposes. The talk parameter is optional, in case it
-- needs to be excluded in the documentation.
--]]
-- Load modules and initialise variables.
mTableTools = require('Module:TableTools')
local namespaces = mw.site.namespaces
local cfg = data.cfg
local useTalk = type(frame) == 'table'
and type(frame.args) == 'table'
and yesno(frame.args.talk) -- Whether to use the talk parameter.
-- Get the header names.
local function checkValue(value, default)
if type(value) == 'string' then
return value
else
return default
end
end
local nsHeader = checkValue(cfg.wikitableNamespaceHeader, 'Namespace')
local aliasesHeader = checkValue(cfg.wikitableAliasesHeader, 'Aliases')
-- Put the namespaces in order.
local mappingsOrdered = {}
for nsname, params in pairs(mappings) do
if useTalk or nsname ~= 'talk' then
local nsid = namespaces[nsname].id
-- Add 1, as the array must start with 1; nsid 0 would be lost otherwise.
nsid = nsid + 1
mappingsOrdered[nsid] = params
end
end
mappingsOrdered = mTableTools.compressSparseArray(mappingsOrdered)
-- Build the table.
local ret = '{| class="wikitable"'
.. '\n|-'
.. '\n! ' .. nsHeader
.. '\n! ' .. aliasesHeader
for i, params in ipairs(mappingsOrdered) do
for j, param in ipairs(params) do
if j == 1 then
ret = ret .. '\n|-'
.. '\n| <code>' .. param .. '</code>'
.. '\n| '
elseif j == 2 then
ret = ret .. '<code>' .. param .. '</code>'
else
ret = ret .. ', <code>' .. param .. '</code>'
end
end
end
ret = ret .. '\n|-'
.. '\n|}'
return ret
end
return p
a4757000273064f151f0f22dc0e139092e5ff443
Module:Namespace detect/data
828
62
140
139
2022-09-04T15:24:41Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Module:Namespace detect/config
828
63
142
141
2022-09-04T15:24:42Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Module:Portal
828
64
144
143
2022-09-04T15:24:42Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[==[ This module is a Lua implementation of the old {{Portal}} template. As of February 2019 it is used on nearly 7,900,000 articles.
-- Please take care when updating it! It outputs two functions: p.portal, which generates a list of portals, and p.image, which
-- produces the image name for an individual portal.
-- The portal image data is kept in submodules of [[Module:Portal/images]], listed below:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
--
-- The images data pages are separated by the first letter to reduce server load when images are added, changed, or removed.
-- Previously all the images were on one data page at [[Module:Portal/images]], but this had the disadvantage that all
-- 5,000,000 pages using this module needed to be refreshed every time an image was added or removed.
]==]
local p = {}
-- determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''
local function sandboxVersion(s)
return isSandbox and s..'-sand' or s
end
local templatestyles = 'Module:Portal'..sandbox..'/styles.css'
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
-- List of non-talk namespaces which should not be tracked (Talk pages are never tracked)
local badNamespaces = {'user','template','draft','wikipedia'}
-- Check whether to do tracking in this namespace
-- Returns true unless the page is one of the banned namespaces
local function checkTracking(title)
local thisPage = title or mw.title.getCurrentTitle()
if thisPage.isTalkPage then
return false
end
local ns = thisPage.nsText:lower()
for _, v in ipairs(badNamespaces) do
if ns == v then
return false
end
end
return true
end
local function matchImagePage(s)
-- Finds the appropriate image subpage given a lower-case
-- portal name plus the first letter of that portal name.
if type(s) ~= 'string' or #s < 1 then return end
local firstLetter = mw.ustring.sub(s, 1, 1)
local imagePage
if mw.ustring.find(firstLetter, '^[a-z]') then
imagePage = 'Module:Portal/images/' .. firstLetter .. sandbox
else
imagePage = 'Module:Portal/images/other' .. sandbox
end
return mw.loadData(imagePage)[s]
end
local function getAlias(s)
-- Gets an alias from the image alias data page.
local aliasData = mw.loadData('Module:Portal/images/aliases'..sandbox)
for portal, aliases in pairs(aliasData) do
for _, alias in ipairs(aliases) do
if alias == s then
return portal
end
end
end
end
local function getImageName(s)
-- Gets the image name for a given string.
local default = 'Portal-puzzle.svg|link=|alt='
if type(s) ~= 'string' or #s < 1 then
return default
end
s = mw.ustring.lower(s)
return matchImagePage(s) or matchImagePage(getAlias(s)) or default
end
-- Function to check argument portals for errors, generate tracking categories if needed
-- Function first checks for too few/many portals provided
-- Then checks the portal list to purge any portals that don't exist
-- Arguments:
-- portals: raw list of portals
-- args.tracking: is tracking requested? (will not track on bad titles or namespaces)
-- args.redlinks: should redlinks be displayed?
-- args.minPortals: minimum number of portal arguments
-- args.maxPortals: maximum number of portal arguments
-- Returns:
-- portals = list of portals, with redlinks purged (if args.redlinks=false)
-- trackingCat = possible tracking category
-- errorMsg = error message
function p._checkPortals(portals, args)
local trackingCat = ''
local errMsg = nil
-- Tracking is on by default.
-- It is disabled if any of the following is true
-- 1/ the parameter "tracking" is set to 'no, 'n', or 'false'
-- 2/ the current page fails the namespace or pagename tests
local trackingEnabled = args.tracking and checkTracking()
args.minPortals = args.minPortals or 1
args.maxPortals = args.maxPortals or -1
-- check for too few portals
if #portals < args.minPortals then
errMsg = 'please specify at least '..args.minPortals..' portal'..(args.minPortals > 1 and 's' or '')
trackingCat = (trackingEnabled and '[[Category:Portal templates with too few portals]]' or '')
return portals, trackingCat, errMsg
end
-- check for too many portals
if args.maxPortals >= 0 and #portals > args.maxPortals then
errMsg = 'too many portals (maximum = '..args.maxPortals..')'
trackingCat = (trackingEnabled and '[[Category:Portal templates with too many portals]]' or '')
return portals, trackingCat, errMsg
end
if not args.redlinks or trackingEnabled then
-- make new list of portals that exist
local existingPortals = {}
for _, portal in ipairs(portals) do
local portalTitle = mw.title.new(portal,"Portal")
-- if portal exists, put it into list
if portalTitle and portalTitle.exists then
table.insert(existingPortals,portal)
-- otherwise set tracking cat
elseif trackingEnabled then
trackingCat = "[[Category:Portal templates with redlinked portals]]"
end
end
-- If redlinks is off, use portal list purged of redlinks
portals = args.redlinks and portals or existingPortals
-- if nothing left after purge, set tracking cat
if #portals == 0 and trackingEnabled then
trackingCat = trackingCat.."[[Category:Pages with empty portal template]]"
end
end
return portals, trackingCat, errMsg
end
function p._portal(portals, args)
-- This function builds the portal box used by the {{portal}} template.
-- Normalize all arguments
if args.redlinks == 'include' then args.redlinks = true end
args.addBreak = args['break']
for key, default in pairs({left=false,tracking=true,nominimum=false,
redlinks=false,addBreak=false,border=true}) do
if args[key] == nil then args[key] = default end
args[key] = yesno(args[key], default)
end
local root = mw.html.create('div')
:attr('role', 'navigation')
:attr('aria-label', 'Portals')
:addClass('noprint plainlist')
:addClass(sandboxVersion('portalbox'))
:addClass(args.border and sandboxVersion('portalborder') or '')
:addClass(args.left and 'tleft' or 'tright')
:css('margin', args.margin or nil)
:newline()
local trackingCat = ''
local errMsg = nil
args.minPortals = args.nominimum and 0 or 1
args.maxPortals = -1
portals, trackingCat, errMsg = p._checkPortals(portals, args)
root:wikitext(trackingCat)
-- if error message, put it in the box and return
if errMsg then
if args.border then -- suppress error message when border=no
local errTag = root:tag('strong')
errTag:addClass('error')
errTag:css('padding','0.2em')
errTag:wikitext('Error: '..errMsg)
end
return tostring(root)
end
-- if no portals (and no error), just return tracking category
if #portals == 0 then
return trackingCat
end
-- Start the list. This corresponds to the start of the wikitext table in the old [[Template:Portal]].
local listroot = root:tag('ul')
:css('width', (tonumber(args.boxsize) or 0) > 0 and (args.boxsize .. 'px') or args.boxsize)
-- Display the portals specified in the positional arguments.
for _, portal in ipairs(portals) do
local image = getImageName(portal)
-- Generate the html for the image and the portal name.
listroot
:newline()
:tag('li')
:tag('span')
:wikitext(string.format('[[File:%s|32x28px|class=noviewer]]', image))
:done()
:tag('span')
:wikitext(string.format('[[Portal:%s|%s%sportal]]', portal, portal, args.addBreak and '<br />' or ' '))
end
return tostring(root)
end
function p._image(portal,nostrip)
-- Wrapper function to allow getImageName() to be accessed through #invoke.
-- backward compatibility: if table passed, take first element
if type(portal) == 'table' then
portal = portal[1]
end
local name = getImageName(portal)
-- If nostrip is yes (or equivalent), then allow all metadata (like image borders) to be returned
local strip = not yesno(nostrip)
return strip and name:match('^(.-)|') or name -- FIXME: use a more elegant way to separate borders etc. from the image name
end
local function getAllImageTables()
-- Returns an array containing all image subpages (minus aliases) as loaded by mw.loadData.
local images = {}
for i, subpage in ipairs{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'other'} do
images[i] = mw.loadData('Module:Portal/images/' .. subpage .. sandbox)
end
return images
end
function p._displayAll(portals, args)
-- This function displays all portals that have portal images. This function is for maintenance purposes and should not be used in
-- articles, for two reasons: 1) there are over 1500 portals with portal images, and 2) the module doesn't record how the portal
-- names are capitalized, so the portal links may be broken.
local lang = mw.language.getContentLanguage()
local count = 1
for _, imageTable in ipairs(getAllImageTables()) do
for portal in pairs(imageTable) do
portals[count] = lang:ucfirst(portal)
count = count + 1
end
end
return p._portal(portals, args)
end
function p._imageDupes()
-- This function searches the image subpages to find duplicate images. If duplicate images exist, it is not necessarily a bad thing,
-- as different portals might just happen to choose the same image. However, this function is helpful in identifying images that
-- should be moved to a portal alias for ease of maintenance.
local exists, dupes = {}, {}
for _, imageTable in ipairs(getAllImageTables()) do
for portal, image in pairs(imageTable) do
if not exists[image] then
exists[image] = portal
else
table.insert(dupes, string.format('The image "[[:File:%s|%s]]" is used for both portals "%s" and "%s".', image, image, exists[image], portal))
end
end
end
if #dupes < 1 then
return 'No duplicate images found.'
else
return 'The following duplicate images were found:\n* ' .. table.concat(dupes, '\n* ')
end
end
local function processPortalArgs(args)
-- This function processes a table of arguments and returns two tables: an array of portal names for processing by ipairs, and a table of
-- the named arguments that specify style options, etc. We need to use ipairs because we want to list all the portals in the order
-- they were passed to the template, but we also want to be able to deal with positional arguments passed explicitly, for example
-- {{portal|2=Politics}}. The behaviour of ipairs is undefined if nil values are present, so we need to make sure they are all removed.
args = type(args) == 'table' and args or {}
local portals = {}
local namedArgs = {}
for k, v in pairs(args) do
if type(k) == 'number' and type(v) == 'string' then -- Make sure we have no non-string portal names.
table.insert(portals, k)
elseif type(k) ~= 'number' then
namedArgs[k] = v
end
end
table.sort(portals)
for i, v in ipairs(portals) do
portals[i] = args[v]
end
return portals, namedArgs
end
-- Entry point for sorting portals from other named arguments
function p._processPortalArgs(args)
return processPortalArgs(args)
end
function p.image(frame)
local origArgs = getArgs(frame)
local portals, args = processPortalArgs(origArgs)
return p._image(portals[1],args.border)
end
local function makeWrapper(funcName)
-- Processes external arguments and sends them to the other functions.
return function (frame)
-- If called via #invoke, use the args passed into the invoking
-- template, or the args passed to #invoke if any exist. Otherwise
-- assume args are being passed directly in from the debug console
-- or from another Lua module.
-- Also: trim whitespace and remove blank arguments
local origArgs = getArgs(frame)
-- create two tables to pass to func: an array of portal names, and a table of named arguments.
local portals, args = processPortalArgs(origArgs)
local results = ''
if funcName == '_portal' or funcName == '_displayAll' then
results = frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles} }
end
return results .. p[funcName](portals, args)
end
end
for _, funcName in ipairs{'portal', 'imageDupes', 'displayAll'} do
p[funcName] = makeWrapper('_' .. funcName)
end
return p
078bc1925b1a76f62f668379257fd789d6d85d4b
Template:Short description
10
65
146
145
2022-09-04T15:24:43Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#ifeq:{{lc:{{{1|}}}}}|none|<nowiki /><!--Prevents whitespace issues when used with adjacent newlines-->|<div class="shortdescription nomobile noexcerpt noprint searchaux" style="display:none">{{{1|}}}{{SHORTDESC:{{{1|}}}|{{{2|}}}}}</div>}}<includeonly>{{#ifeq:{{pagetype |defaultns = all |user=exclude}}|exclude||[[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with short description{{#ifeq:{{{pagetype}}}|Disambiguation pages|s}}]]}}</includeonly><!-- Start tracking
-->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using short description with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Short description]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | pagetype | bot |plural }}<!--
-->{{#ifexpr: {{#invoke:String|len|{{{1|}}}}}>100 | [[Category:{{{pagetype|{{pagetype |defaultns = extended |plural=y}}}}} with long short description]]}}<!--
-->{{Short description/lowercasecheck|{{{1|}}}}}<!--
-->{{Main other |{{SDcat |sd={{{1|}}} }} }}<noinclude>
{{Documentation}}
</noinclude>
a9562f8e6077b84b83132612ac9a5b37c58485b3
Template:Main other
10
66
148
147
2022-09-04T15:24:43Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#switch:
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{lc: {{{demospace}}} }} <!--Use lower case "demospace"-->
| {{#ifeq:{{NAMESPACE}}|{{ns:0}}
| main
| other
}}
}}
| main = {{{1|}}}
| other
| #default = {{{2|}}}
}}<noinclude>
{{documentation}}
<!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
</noinclude>
86ad907ffeea3cc545159e00cd1f2d6433946450
Template:Short description/lowercasecheck
10
67
150
149
2022-09-04T15:24:43Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#ifeq:<!--test first character for lower-case letter-->{{#invoke:string|find|1={{{1|}}}|2=^%l|plain=false}}|1
|<!-- first character is a lower case letter; test against whitelist
-->{{#switch: {{First word|{{{1|}}}}}<!--begin whitelist-->
|c. <!--for circa-->
|gTLD
|iMac
|iOS
|iOS,
|iPad
|iPhone
|iTunes
|macOS
|none
|pH
|pH-dependent=<!-- end whitelist; short description starts with an allowed lower-case string; whitelist matched; do nothing -->
|#default=<!-- apply category to track lower-case short descriptions -->{{main other|[[Category:Pages with lower-case short description|{{trim|{{{1|}}}}}]]}}{{Testcases other|{{red|CATEGORY APPLIED}}}}<!-- end whitelist test -->}}
|<!-- short description does not start with lower-case letter; do nothing; end lower-case test -->
}}<noinclude>
{{documentation}}
</noinclude>
9a6d4db14b74614625fd234b4f8ee3c8e1a235c0
Template:SDcat
10
68
152
151
2022-09-04T15:24:44Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:SDcat |setCat}}</includeonly><noinclude>
{{documentation}}
</noinclude>
8c6e8783ddb0dc699d6fb60370db97b73725b9a6
Template:Str rep
10
69
154
153
2022-09-04T15:24:44Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|1}}<noinclude>
{{Documentation}}</noinclude>
4706daa3137857f2792cc7109ca24b6d58c78dee
Module:Check for unknown parameters
828
70
156
155
2022-09-04T15:24:44Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '<' .. tag .. '>...</' .. tag .. '>')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
return table.concat(res)
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
return p
93db6d115d4328d2a5148bb42959105e367b663e
Module:String
828
71
158
157
2022-09-04T15:24:45Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} )
local s = new_args['s'] or ''
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } )
local s = new_args['s'] or ''
local i = tonumber( new_args['i'] ) or 1
local j = tonumber( new_args['j'] ) or -1
local len = mw.ustring.len( s )
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1
end
if j < 0 then
j = len + j + 1
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'String subset index out of range' )
end
if j < i then
return str._error( 'String subset indices out of order' )
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
_match
This function returns a substring from the source string that matches a
specified pattern. It is exported for use in other modules
Usage:
strmatch = require("Module:String")._match
sresult = strmatch( s, pattern, start, match, plain, nomatch )
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This sub-routine is exported for use in other modules
function str._match( s, pattern, start, match_index, plain_flag, nomatch )
if s == '' then
return str._error( 'Target string is empty' )
end
if pattern == '' then
return str._error( 'Pattern string is empty' )
end
start = tonumber(start) or 1
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Requested start is out of range' )
end
if match_index == 0 then
return str._error( 'Match index is out of range' )
end
if plain_flag then
pattern = str._escapePattern( pattern )
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start )
end
local iterator = mw.ustring.gmatch(s, pattern)
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1
if match_index == 0 then
result = w
break
end
end
else
-- Reverse search
local result_table = {}
local count = 1
for w in iterator do
result_table[count] = w
count = count + 1
end
result = result_table[ count + match_index ]
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Match not found' )
else
return nomatch
end
else
return result
end
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
-- This is the entry point for #invoke:String|match
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} )
local s = new_args['s'] or ''
local start = tonumber( new_args['start'] ) or 1
local plain_flag = str._getBoolean( new_args['plain'] or false )
local pattern = new_args['pattern'] or ''
local match_index = math.floor( tonumber(new_args['match']) or 1 )
local nomatch = new_args['nomatch']
return str._match( s, pattern, start, match_index, plain_flag, nomatch )
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} )
local target_str = new_args['target'] or ''
local pos = tonumber( new_args['pos'] ) or 0
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'String index out of range' )
end
return mw.ustring.sub( target_str, pos, pos )
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} )
local source_str = new_args['source'] or ''
local target_str = new_args['target'] or ''
if target_str == '' then
return 1
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['target'] or ''
local start_pos = tonumber(new_args['start']) or 1
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return 0
end
plain = str._getBoolean( plain )
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['pattern'] or ''
local replace = new_args['replace'] or ''
local count = tonumber( new_args['count'] )
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return source_str
end
plain = str._getBoolean( plain )
if plain then
pattern = str._escapePattern( pattern )
replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
end
local result
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count )
else
result = mw.ustring.gsub( source_str, pattern, replace )
end
return result
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
escapePattern
This function escapes special characters from a Lua string pattern. See [1]
for details on how patterns work.
[1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
Usage:
{{#invoke:String|escapePattern|pattern_string}}
Parameters
pattern_string: The pattern string to escape.
]]
function str.escapePattern( frame )
local pattern_str = frame.args[1]
if not pattern_str then
return str._error( 'No pattern string specified' )
end
local result = str._escapePattern( pattern_str )
return result
end
--[[
count
This function counts the number of occurrences of one string in another.
]]
function str.count(frame)
local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'})
local source = args.source or ''
local pattern = args.pattern or ''
local plain = str._getBoolean(args.plain or true)
if plain then
pattern = str._escapePattern(pattern)
end
local _, count = mw.ustring.gsub(source, pattern, '')
return count
end
--[[
endswith
This function determines whether a string ends with another string.
]]
function str.endswith(frame)
local args = str._getParameters(frame.args, {'source', 'pattern'})
local source = args.source or ''
local pattern = args.pattern or ''
if pattern == '' then
-- All strings end with the empty string.
return "yes"
end
if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then
return "yes"
else
return ""
end
end
--[[
join
Join all non empty arguments together; the first argument is the separator.
Usage:
{{#invoke:String|join|sep|one|two|three}}
]]
function str.join(frame)
local args = {}
local sep
for _, v in ipairs( frame.args ) do
if sep then
if v ~= '' then
table.insert(args, v)
end
else
sep = v
end
end
return table.concat( args, sep or '' )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {}
local index = 1
local value
for _, arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index]
index = index + 1
end
new_args[arg] = value
end
return new_args
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame()
local error_category = frame.args.error_category or 'Errors reported by Module String'
local ignore_errors = frame.args.ignore_errors or false
local no_category = frame.args.no_category or false
if str._getBoolean(ignore_errors) then
return ''
end
local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>'
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Category:' .. error_category .. ']]' .. error_str
end
return error_str
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower()
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false
else
boolean_value = true
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str
else
error( 'No boolean value found' )
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
end
return str
6df794dd52434e0f6a372c9918f5a9dedd15f579
Module:SDcat
828
72
160
159
2022-09-04T15:24:45Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[
SDcat
Module to check whether local short description matches that on Wikidata
--]]
local p = {}
-------------------------------------------------------------------------------
--[[
setCat has the qid of a Wikidata entity passed as |qid=
(it defaults to the associated qid of the current article if omitted)
and the local short description passed as |sd=
It returns a category if there is an associated Wikidata entity.
It returns one of the following tracking categories, as appropriate:
* Category:Short description matches Wikidata (case-insensitive)
* Category:Short description is different from Wikidata
* Category:Short description with empty Wikidata description
For testing purposes, a link prefix |lp= may be set to ":" to make the categories visible.
--]]
-- function exported for use in other modules
-- (local short description, Wikidata entity-ID, link prefix)
p._setCat = function(sdesc, itemID, lp)
if not mw.wikibase then return nil end
if itemID == "" then itemID = nil end
-- Wikidata description field
local wdesc = (mw.wikibase.getDescription(itemID) or ""):lower()
if wdesc == "" then
return "[[" .. lp .. "Category:Short description with empty Wikidata description]]"
elseif wdesc == sdesc then
return "[[" .. lp .. "Category:Short description matches Wikidata]]"
else
return "[[" .. lp .. "Category:Short description is different from Wikidata]]"
end
end
-- function exported for call from #invoke
p.setCat = function(frame)
local args
if frame.args.sd then
args = frame.args
else
args = frame:getParent().args
end
-- local short description
local sdesc = mw.text.trim(args.sd or ""):lower()
-- Wikidata entity-ID
local itemID = mw.text.trim(args.qid or "")
-- link prefix, strip quotes
local lp = mw.text.trim(args.lp or ""):gsub('"', '')
return p._setCat(sdesc, itemID, lp)
end
return p
6c19ac0f72c79a618eb105808f74701376bb2b38
Module:TableTools
828
73
162
161
2022-09-04T15:24:46Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should not --
-- be called directly from #invoke. --
------------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
function p.isPositiveInteger(v)
return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity
end
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false if
-- not. Although it doesn't operate on tables, it is included here as it is useful
-- for determining whether a value can be a valid table key. Lua will generate an
-- error if a NaN is used as a table key.
------------------------------------------------------------------------------------
function p.isNan(v)
return type(v) == 'number' and v ~= v
end
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
function p.shallowClone(t)
checkType('shallowClone', 1, t, 'table')
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
function p.removeDuplicates(arr)
checkType('removeDuplicates', 1, arr, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for _, v in ipairs(arr) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will return
-- {1, 3, 6}.
------------------------------------------------------------------------------------
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
return s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like {"foo1", "bar1", "foo2", "baz2"}, returns a table
-- of subtables in the format
-- {[1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'}}.
-- Keys that don't end with an integer are stored in a subtable named "other". The
-- compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for _ in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
elseif type1 == 'table' or type1 == 'boolean' or type1 == 'function' then
return tostring(item1) < tostring(item2)
else
return item1 < item2
end
end
------------------------------------------------------------------------------------
-- keysToList
--
-- Returns an array of the keys in a table, sorted using either a default
-- comparison function or a custom keySort function.
------------------------------------------------------------------------------------
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, {'function', 'boolean', 'nil'})
end
local arr = {}
local index = 1
for k in pairs(t) do
arr[index] = k
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(arr, keySort)
end
return arr
end
------------------------------------------------------------------------------------
-- sortedPairs
--
-- Iterates through a table, with the keys sorted using the keysToList function.
-- If there are only numerical keys, sparseIpairs is probably more efficient.
------------------------------------------------------------------------------------
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local arr = p.keysToList(t, keySort, true)
local i = 0
return function ()
i = i + 1
local key = arr[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
------------------------------------------------------------------------------------
-- isArray
--
-- Returns true if the given value is a table and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArray(v)
if type(v) ~= 'table' then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- isArrayLike
--
-- Returns true if the given value is iterable and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArrayLike(v)
if not pcall(pairs, v) then
return false
end
local i = 0
for _ in pairs(v) do
i = i + 1
if v[i] == nil then
return false
end
end
return true
end
------------------------------------------------------------------------------------
-- invert
--
-- Transposes the keys and values in an array. For example, {"a", "b", "c"} ->
-- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to
-- the index of the last duplicate) and NaN values are ignored.
------------------------------------------------------------------------------------
function p.invert(arr)
checkType("invert", 1, arr, "table")
local isNan = p.isNan
local map = {}
for i, v in ipairs(arr) do
if not isNan(v) then
map[v] = i
end
end
return map
end
------------------------------------------------------------------------------------
-- listToSet
--
-- Creates a set from the array part of the table. Indexing the set by any of the
-- values of the array returns true. For example, {"a", "b", "c"} ->
-- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them
-- never equal to any value (including other NaNs or even themselves).
------------------------------------------------------------------------------------
function p.listToSet(arr)
checkType("listToSet", 1, arr, "table")
local isNan = p.isNan
local set = {}
for _, v in ipairs(arr) do
if not isNan(v) then
set[v] = true
end
end
return set
end
------------------------------------------------------------------------------------
-- deepCopy
--
-- Recursive deep copy function. Preserves identities of subtables.
------------------------------------------------------------------------------------
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = _deepCopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
------------------------------------------------------------------------------------
-- sparseConcat
--
-- Concatenates all values in the table that are indexed by a number, in order.
-- sparseConcat{a, nil, c, d} => "acd"
-- sparseConcat{nil, b, c, d} => "bcd"
------------------------------------------------------------------------------------
function p.sparseConcat(t, sep, i, j)
local arr = {}
local arr_i = 0
for _, v in p.sparseIpairs(t) do
arr_i = arr_i + 1
arr[arr_i] = v
end
return table.concat(arr, sep, i, j)
end
------------------------------------------------------------------------------------
-- length
--
-- Finds the length of an array, or of a quasi-array with keys such as "data1",
-- "data2", etc., using an exponential search algorithm. It is similar to the
-- operator #, but may return a different value when there are gaps in the array
-- portion of the table. Intended to be used on data loaded with mw.loadData. For
-- other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of the number
-- of unnamed template parameters, so use this function for frame.args.
------------------------------------------------------------------------------------
function p.length(t, prefix)
-- requiring module inline so that [[Module:Exponential search]] which is
-- only needed by this one function doesn't get millions of transclusions
local expSearch = require("Module:Exponential search")
checkType('length', 1, t, 'table')
checkType('length', 2, prefix, 'string', true)
return expSearch(function (i)
local key
if prefix then
key = prefix .. tostring(i)
else
key = i
end
return t[key] ~= nil
end) or 0
end
------------------------------------------------------------------------------------
-- inArray
--
-- Returns true if valueToFind is a member of the array, and false otherwise.
------------------------------------------------------------------------------------
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
085e7094ac84eb0132ee65822cf3f69cd8ba3d81
Module:Separated entries
828
74
164
163
2022-09-04T15:24:46Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux". The starting parameter can also be specified.
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard values before the starting parameter.
local start = tonumber(args.start)
if start then
for i = 1, start - 1 do args[i] = nil end
end
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction, first)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
args.first = first or args.first
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
e80231ff3de01afd7f62a94e0a34dc1e67504085
Module:Category handler
828
75
166
165
2022-09-04T15:24:46Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Module:Category handler/data
828
76
168
167
2022-09-04T15:24:47Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Module:Category handler/config
828
77
170
169
2022-09-04T15:24:47Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Module:Category handler/shared
828
78
172
171
2022-09-04T15:24:47Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Module:Category handler/blacklist
828
79
174
173
2022-09-04T15:24:48Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template index/.*$',
-- Don't categorise archives.
'/[aA]rchive',
"^Wikipedia:Administrators' noticeboard/IncidentArchive%d+$",
}
87469d7a9ef2a3c41b2bf04ae18f7c59a18fb855
Template:IPAc-en
10
80
176
175
2022-09-04T15:24:48Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:IPAc-en|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
f81b884979df2c3ec3a7275e7fb402ad585e26e4
Module:IPAc-en
828
81
178
177
2022-09-04T15:24:49Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module implements [[Template:IPAc-en]].
local data = mw.loadData('Module:IPAc-en/data')
local p = {}
-- Global container for tracking categories
local categoryHandler = require('Module:Category handler').main
local categories = {}
-- Trims whitespace from a string
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
-- This implements [[Template:Nowrap]].
local function makeNowrapSpan(s)
local span = mw.html.create('span')
:addClass('rt-commentedText') -- Works with [[MediaWiki:Gadget-ReferenceTooltips.js]]
:addClass('nowrap')
:wikitext(s)
return tostring(span)
end
local function makePronunciationText(id)
id = id and string.lower(trim(id))
if id and id ~= '' and data.pronunciation[id] then
return data.pronunciation[id].text
end
end
-- This adds a tooltip icon to a label. It implements [[Template:H:title]].
local function makeTooltip(label, tooltip)
local span = mw.html.create('span')
:attr('title', tooltip)
:wikitext(label)
return tostring(span)
end
local function formatPhonemeGroup(phonemes)
if #phonemes > 0 then
local span = mw.html.create('span')
:css('border-bottom', '1px dotted')
:wikitext(table.concat(phonemes))
return tostring(span)
else
return ''
end
end
local function renderCategories()
local ret = ''
if categoryHandler{ true } then
ret = {}
for cat in pairs(categories) do
table.insert(ret, string.format('[[Category:%s]]', cat))
end
table.sort(ret)
ret = table.concat(ret)
else
ret = ''
end
return ret
end
function p._main(args)
local ret = {}
local i = 0 -- Keeps track of numbered args
-- Pronunciation
do
local pron = {}
while true do
i = i + 1
local pronItem = makePronunciationText(args[i])
if pronItem then
pron[#pron + 1] = pronItem
pron[#pron + 1] = ' '
else
break
end
end
if #pron > 0 then
ret[#ret + 1] = string.format(
'<small>%s</small>',
table.concat(pron)
)
end
end
-- Phonemes
do
-- Loop through the numbered args, separating them into phoneme groups
-- and separator strings (both called "words" for convenience). We only
-- underline the phoneme groups, not the separators.
local words = {}
words[#words + 1] = '/' -- Opening slash
i = i - 1 -- Set up i again as it was changed in the pronunciation loop
local id
repeat
local phonemes = {}
local isWordEnd = false
while not isWordEnd do
i = i + 1
id = args[i]
id = id and trim(id)
if not id then
isWordEnd = true
words[#words + 1] = formatPhonemeGroup(phonemes)
elseif id ~= '' then
local t = data.phonemes[id]
if not t then
-- We were passed an invalid id.
isWordEnd = true
categories["Ill-formatted IPAc-en transclusions"] = true
words[#words + 1] = formatPhonemeGroup(phonemes)
words[#words + 1] = makeTooltip(
string.format(
"<strong class=\"error\">[invalid input: '%s']</strong>",
id
),
'Unrecognized symbol'
)
elseif not t.label then
-- The data module contains bad data, so throw an error.
error(string.format(
"no label was found for id '%s'",
tostring(id)
))
elseif t.tooltip then
-- We are dealing with a regular phoneme.
phonemes[#phonemes + 1] = makeTooltip(
t.label,
t.tooltip
)
else
-- We are dealing with a separator.
isWordEnd = true
words[#words + 1] = formatPhonemeGroup(phonemes)
words[#words + 1] = t.label
end
end
end
until not id
words[#words + 1] = '/' -- Closing slash
-- Wrap the words in a link to IPA help.
local span = mw.html.create('span')
-- Suppress Navigation popups and Page Previews (aka Hovercards)
:addClass('IPA nopopups noexcerpt')
:attr('lang', 'en-fonipa')
:wikitext(string.format(
'[[Help:IPA/English|%s]]',
table.concat(words)
))
ret[#ret + 1] = tostring(span)
end
-- Audio link
do
local file = args.audio and trim(args.audio)
if file and file ~= '' then
categories["Pages including recorded pronunciations"] = true
ret[#ret + 1] = mw.getCurrentFrame():expandTemplate{
title = 'Template:IPA audio link', args = { file, attribution = args.attribution } }
end
end
-- Nowrap and categories
ret = makeNowrapSpan(table.concat(ret)) .. renderCategories()
-- Reset the categories table in case we are run again.
categories = {}
return ret
end
function p.main(frame)
return p._main(frame:getParent().args)
end
return p
62c540dcdc647c5bc63614ba04eabf7f645dd284
Module:IPAc-en/data
828
82
180
179
2022-09-04T15:24:49Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module processes data for [[Module:IPAc-en]]. It is intended to be
-- loaded with mw.loadData.
local PRONUNCIATION_MODULE = 'Module:IPAc-en/pronunciation'
local PHONEME_MODULE = 'Module:IPAc-en/phonemes'
local function makeData(oldData)
local newData = {}
for i, old in ipairs(oldData) do
local new = {}
for k, v in pairs(old) do
if k ~= 'aliases' and k ~= 'code' then
new[k] = v
end
end
newData[old.code] = new
if old.aliases then
for i, alias in ipairs(old.aliases) do
newData[alias] = new
end
end
end
return newData
end
local function main()
local pronunciation = makeData(require(PRONUNCIATION_MODULE))
local phonemes = makeData(require(PHONEME_MODULE))
-- Check that no pronunciation keys are also contained in the phonemes
-- data. This would cause silent, hard-to-debug errors if it went
-- unchecked, so make it cause a big red error message instead.
for id in pairs(pronunciation) do
if phonemes[id] then
error(string.format(
"duplicate ID '%s' found in %s and %s",
id,
PRONUNCIATION_MODULE,
PHONEME_MODULE
))
end
end
return {
pronunciation = pronunciation,
phonemes = phonemes,
}
end
return main()
3428d5574793b97b1b5ba91ff0c32e0418c27642
Module:IPAc-en/pronunciation
828
83
182
181
2022-09-04T15:24:49Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module contains pronunciation-key data for [[Module:IPAc-en]].
return {
{
code = 'lang',
text = 'English:'
},
{
code = 'pron',
text = ''
},
{
code = 'local',
text = 'locally'
},
{
code = 'ipa',
text = '[[International Phonetic Alphabet|IPA]]:'
},
{
code = 'also',
text = 'also'
},
{
code = 'uk',
text = '[[British English|UK]]:'
},
{
code = 'us',
text = '[[American English|US]]:'
},
{
code = 'uklang',
text = '[[British English]]:'
},
{
code = 'uslang',
text = '[[American English]]:'
},
{
code = 'ukalso',
text = '[[British English|UK]] also'
},
{
code = 'usalso',
text = '[[American English|US]] also'
},
{
code = 'alsouk',
text = 'also [[British English|UK]]:'
},
{
code = 'alsous',
text = 'also [[American English|US]]:'
},
}
f4b022e065c591350dd1ee03942c104a3a096395
Module:IPAc-en/phonemes
828
84
184
183
2022-09-04T15:24:50Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module contains phoneme data for [[Module:IPAc-en]].
return {
-- CONSONANTS
{
code = "b",
label = "b",
tooltip = "'b' in 'buy'",
},
{
code = "d",
label = "d",
tooltip = "'d' in 'dye'",
},
{
code = "dj",
aliases = {"dy", "dʲ"},
label = "dj",
tooltip = "/dj/: 'd' in 'dew'",
},
{
code = "dʒ",
aliases = {"dZ", "ʤ"},
label = "dʒ",
tooltip = "/dʒ/: 'j' in 'jam'",
},
{
code = "ð",
aliases = {"D"},
label = "ð",
tooltip = "/ð/: 'th' in 'this'",
},
{
code = "f",
label = "f",
tooltip = "'f' in 'find'",
},
{
code = "ɡ",
aliases = {"g"},
label = "ɡ",
tooltip = "/ɡ/: 'g' in 'guy'",
},
{
code = "h",
label = "h",
tooltip = "'h' in 'hi'",
},
{
code = "hw",
aliases = {"ʍ"},
label = "hw",
tooltip = "/hw/: 'wh' in 'why'",
},
{
code = "j",
aliases = {"y"},
label = "j",
tooltip = "/j/: 'y' in 'yes'",
},
{
code = "k",
label = "k",
tooltip = "'k' in 'kind'",
},
{
code = "l",
label = "l",
tooltip = "'l' in 'lie'",
},
{
code = "lj",
aliases = {"ly", "lʲ"},
label = "lj",
tooltip = "/lj/: 'l' in 'lute'",
},
{
code = "m",
label = "m",
tooltip = "'m' in 'my'",
},
{
code = "n",
label = "n",
tooltip = "'n' in 'nigh'",
},
{
code = "nj",
aliases = {"ny", "nʲ"},
label = "nj",
tooltip = "/nj/: 'n' in 'new'",
},
{
code = "ŋ",
aliases = {"N", "ng"},
label = "ŋ",
tooltip = "/ŋ/: 'ng' in 'sing'",
},
{
code = "p",
label = "p",
tooltip = "'p' in 'pie'",
},
{
code = "r",
aliases = {"ɹ", "ɻ"},
label = "r",
tooltip = "'r' in 'rye'",
},
{
code = "s",
label = "s",
tooltip = "'s' in 'sigh'",
},
{
code = "sj",
aliases = {"sy", "sʲ"},
label = "sj",
tooltip = "/sj/: 's' in 'consume'",
},
{
code = "ʃ",
aliases = {"S", "sh"},
label = "ʃ",
tooltip = "/ʃ/: 'sh' in 'shy'",
},
{
code = "t",
label = "t",
tooltip = "'t' in 'tie'",
},
{
code = "tj",
aliases = {"ty", "tʲ"},
label = "tj",
tooltip = "/tj/: 't' in 'tune'",
},
{
code = "tʃ",
aliases = {"tS", "ʧ", "ch"},
label = "tʃ",
tooltip = "/tʃ/: 'ch' in 'China'",
},
{
code = "θ",
aliases = {"T"},
label = "θ",
tooltip = "/θ/: 'th' in 'thigh'",
},
{
code = "θj",
aliases = {"θy", "θʲ"},
label = "θj",
tooltip = "/θj/: 'th' in 'enthuse'",
},
{
code = "v",
label = "v",
tooltip = "'v' in 'vie'",
},
{
code = "w",
label = "w",
tooltip = "'w' in 'wind'",
},
{
code = "z",
label = "z",
tooltip = "'z' in 'zoom'",
},
{
code = "zj",
aliases = {"zy", "zʲ"},
label = "zj",
tooltip = "/zj/: 'Z' in 'Zeus'",
},
{
code = "ʒ",
aliases = {"Z", "zh"},
label = "ʒ",
tooltip = "/ʒ/: 's' in 'pleasure'",
},
-- VOWELS
{
code = "ɑː",
aliases = {"A:", "ɑ:", "aː", "a:"},
label = "ɑː",
tooltip = "/ɑː/: 'a' in 'father'",
},
{
code = "ɑːr",
aliases = {"ɑɹ", "aːr", "a:r", "ɑ:r", "ɑr"},
label = "ɑːr",
tooltip = "/ɑːr/: 'ar' in 'far'",
},
{
code = "ɒ",
aliases = {"Q"},
label = "ɒ",
tooltip = "/ɒ/: 'o' in 'body'",
},
{
code = "ɒr",
aliases = {"Qr"},
label = "ɒr",
tooltip = "/ɒr/: 'or' in 'moral'",
},
{
code = "æ",
aliases = {"ae", "{"},
label = "æ",
tooltip = "/æ/: 'a' in 'bad'",
},
{
code = "ær",
aliases = {"aer", "&r", "æɹ"},
label = "ær",
tooltip = "/ær/: 'arr' in 'marry'",
},
{
code = "aɪ",
aliases = {"ai", "aI"},
label = "aɪ",
tooltip = "/aɪ/: 'i' in 'tide'",
},
{
code = "aɪər",
aliases = {"aɪr", "aIr", "aɪə"},
label = "aɪər",
tooltip = "/aɪər/: 'ire' in 'fire'",
},
{
code = "aʊ",
aliases = {"au", "aU"},
label = "aʊ",
tooltip = "/aʊ/: 'ou' in 'mouth'",
},
{
code = "aʊər",
aliases = {"aʊr", "aUr", "aʊə", "aur"},
label = "aʊər",
tooltip = "/aʊər/: 'our' in 'hour'",
},
{
code = "ɛ",
aliases = {"E"},
label = "ɛ",
tooltip = "/ɛ/: 'e' in 'dress'",
},
{
code = "ɛr",
aliases = {"Er"},
label = "ɛr",
tooltip = "/ɛr/: 'err' in 'merry'",
},
{
code = "eɪ",
aliases = {"ei", "eI", "eː", "e:"},
label = "eɪ",
tooltip = "/eɪ/: 'a' in 'face'",
},
{
code = "ɛər",
aliases = {"eir", "eIr", "e@r", "E@r", "ɛɪɹ", "eɪr", "eːr", "e:r", "ɛəɹ", "ɛə", "ɛːr", "ɛ:r", "ɛː", "ɛ:", "E:", "E:r"},
label = "ɛər",
tooltip = "/ɛər/: 'are' in 'bare'",
},
{
code = "ɛəˈr",
aliases = {"ɛə'r", "eəˈr", "eə'r", "e@'r", "E@'r", "ɛːˈr", "E:'r"},
label = "ɛəˈr",
tooltip = "/ɛəˈr/: 'ere' in 'thereof'",
},
{
code = "ɛəˌr",
aliases = {"ɛə,r", "eəˌr", "eə,r", "E@,r", "E@%r", "e@,r", "e@%r", "ɛːˌr", "E:,r", "E:%r"},
label = "ɛəˌr",
tooltip = "/ɛəˌr/: 'ere' in 'thereof'",
},
{
code = "ɪ",
aliases = {"I", "ᵻ"},
label = "ɪ",
tooltip = "/ɪ/: 'i' in 'kit'",
},
{
code = "ɪr",
label = "ɪr",
tooltip = "/ɪr/: 'irr' in 'mirror'",
},
{
code = "iː",
aliases = {"i:"},
label = "iː",
tooltip = "/iː/: 'ee' in 'fleece'",
},
{
code = "ɪər",
aliases = {"i:r", "iːr", "I@r", "i@r", "ɪəɹ", "iːɹ", "ɪə"},
label = "ɪər",
tooltip = "/ɪər/: 'ear' in 'near'",
},
{
code = "ɪəˈr",
aliases = {"ɪə'r", "I@'r"},
label = "ɪəˈr",
tooltip = "/ɪəˈr/: 'er' in 'spheroidal'",
},
{
code = "ɪəˌr",
aliases = {"ɪə,r", "I@,r", "I@%r"},
label = "ɪəˌr",
tooltip = "/ɪəˌr/: 'er' in 'spheroidal'",
},
{
code = "oʊ",
aliases = {"o:", "oː", "ou", "oU", "@u", "@U", "əʊ", "əu", "oʊ-"},
label = "oʊ",
tooltip = "/oʊ/: 'o' in 'code'",
},
{
code = "ɔː",
aliases = {"O", "O:", "ɔ:", "ɒː", "Q:"},
label = "ɔː",
tooltip = "/ɔː/: 'au' in 'fraud'",
},
{
code = "ɔːr",
aliases = {"Or", "ɔɹ", "ɔ(r)", "ɔr", "ɔər", "oUr", "ɔəɹ", "ɔʊɹ", "oʊɹ", "oʊr", "oːr", "o:r", "ɔə", "ɔə(r)"},
label = "ɔːr",
tooltip = "/ɔːr/: 'ar' in 'war'",
},
{
code = "ɔɪ",
aliases = {"oj", "ɔj", "oi", "oɪ", "ɔi", "OI", "oy"},
label = "ɔɪ",
tooltip = "/ɔɪ/: 'oi' in 'choice'",
},
{
code = "ɔɪər",
aliases = {"ɔɪr", "oyr", "ɔɪə"},
label = "ɔɪər",
tooltip = "/ɔɪər/: 'oir' in 'coir'",
},
{
code = "ʊ",
aliases = {"U", "ᵿ"},
label = "ʊ",
tooltip = "/ʊ/: 'u' in 'push'",
},
{
code = "ʊr",
aliases = {"Ur"},
label = "ʊr",
tooltip = "/ʊr/: 'our' in 'courier'",
},
{
code = "uː",
aliases = {"u:"},
label = "uː",
tooltip = "/uː/: 'oo' in 'goose'",
},
{
code = "ʊər",
aliases = {"u:r", "uːr", "u@r", "U@r", "ʊəɹ", "ʊə"},
label = "ʊər",
tooltip = "/ʊər/: 'our' in 'tour'",
},
{
code = "ʊəˈr",
aliases = {"ʊə'r", "U@'r"},
label = "ʊəˈr",
tooltip = "/ʊəˈr/: 'ur' in 'plurality'",
},
{
code = "ʊəˌr",
aliases = {"ʊə,r", "U@,r", "U@%r"},
label = "ʊəˌr",
tooltip = "/ʊəˌr/: 'ur' in 'plurality'",
},
{
code = "ʌ",
aliases = {"V"},
label = "ʌ",
tooltip = "/ʌ/: 'u' in 'cut'",
},
{
code = "ʌr",
aliases = {"Vr", "ʌɹ"},
label = "ʌr",
tooltip = "/ʌr/: 'urr' in 'hurry'",
},
{
code = "ɜːr",
aliases = {"ɝː", "ɝ", "3r", "3:r", "əːr", "@:r", "ɜɹ", "ɜ(r)", "ɜr"},
label = "ɜːr",
tooltip = "/ɜːr/: 'ur' in 'fur'",
},
{
code = "ə",
aliases = {"@"},
label = "ə",
tooltip = "/ə/: 'a' in 'about'",
},
-- SYLLABIC CONSONANTS
{
code = "ər",
aliases = {"ɚ", "@r", "əɹ", "ə(r)"},
label = "ər",
tooltip = "/ər/: 'er' in 'letter'",
},
{
code = "əl",
aliases = {"@l", "ᵊl", "l̩"},
label = "əl",
tooltip = "/əl/: 'le' in 'bottle'",
},
{
code = "ən",
aliases = {"@n", "ᵊn", "n̩"},
label = "ən",
tooltip = "/ən/: 'on' in 'button'",
},
{
code = "əm",
aliases = {"@m", "ᵊm", "m̩"},
label = "əm",
tooltip = "/əm/: 'm' in 'rhythm'",
},
-- ARCHIPHONEMES
{
code = "i",
label = "i",
tooltip = "/i/: 'y' in 'happy'",
},
{
code = "u",
label = "u",
tooltip = "/u/: 'u' in 'influence'",
},
-- MARGINAL SEGMENTS
{
code = "x",
label = "x",
aliases = {"kh"},
tooltip = "/x/: 'ch' in 'loch'",
},
{
code = "ʔ",
aliases = {"?"},
label = "ʔ",
tooltip = "/ʔ/: the catch in 'uh-oh'",
},
{
code = "ɒ̃",
aliases = {"ɑ̃", "ɒ~", "ɑ~", "Q~"},
label = "ɒ̃",
tooltip = "/ɒ̃/: nasal 'an' in 'vin blanc'",
},
{
code = "æ̃",
aliases = {"ae~", "{~", "ã", "a~"},
label = "æ̃",
tooltip = "/æ̃/: nasal 'in' in 'vin blanc'",
},
{
code = "ɜː",
aliases = {"3", "3:", "ɜ:", "ɜ", "əː", "@:"},
label = "ɜː",
tooltip = "/ɜː/: r-less 'ur' in 'nurse'",
},
-- SUPRASEGMENTALS
{
code = "ˈ",
aliases = {"'", '"'},
label = "ˈ",
tooltip = "/ˈ/: primary stress follows",
},
{
code = "ˌ",
aliases = {",", "%"},
label = "ˌ",
tooltip = "/ˌ/: secondary stress follows",
},
{
code = ".",
aliases = {"·"},
label = ".",
tooltip = "/./: syllable break",
},
{
code = "#",
label = "#",
tooltip = "/#/: morpheme break",
},
{
code = "!",
label = "|",
tooltip = "/|/: prosodic break (minor)",
},
{
code = "!!",
aliases = {"‖"},
label = "‖",
tooltip = "/‖/: prosodic break (major)",
},
-- SEPARATORS
-- Tables without tooltip text are used as word separators. In addition to
-- not having any tooltip text in the template output, they are not
-- underlined.
{
code = "_",
label = "<span class=\"wrap\"> </span>",
},
{
code = "nbsp",
aliases = {" "},
label = " ",
},
{
code = ",_",
label = ",<span class=\"wrap\"> </span>",
},
{
code = "-",
aliases = {"–"},
label = "-",
},
{
code = "(",
label = "(",
},
{
code = ")",
label = ")",
},
-- This is useful for highly variable words in place names, which are not
-- important to transcribe.
{
code = "...",
label = " ...<span class=\"wrap\"> </span>",
},
-- Obsolete combinations, kept for compatibility
{
code = "juː",
label = "juː",
tooltip = "/juː/: 'u' in 'cute'",
},
{
code = "jʊər",
label = "jʊər",
tooltip = "/jʊər/: 'ure' in 'cure'",
},
}
edb55389474ac8485fc15b3386eebeb0c44b7263
Template:Cite web
10
85
186
185
2022-09-04T15:24:50Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=web
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
ea1b0f38afd9728a1cf9f2e3f540887a402fab8e
Module:Portal/images/s
828
86
188
187
2022-09-04T15:24:51Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[==[ This is the "S" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "S". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be omitted.
]==]
return {
["saarc"] = "SAARC 1717549468.png|link=|alt=icon",
["saarland"] = "Flag of Saarland.svg|border|link=|alt=flag",
["saba"] = "Flag of Saba.svg|border|link=|alt=flag",
["sabah"] = "Flag of Sabah.svg|border|link=|alt=flag",
["sacred christian music"] = "Musical note nicu bucule 01.svg|link=|alt=icon",
["saguenay–lac-saint-jean"] = "Flag of Saguenay-Lac-Saint-Jean.svg|border|link=|alt=flag",
["sailing"] = "Sailing pictogram.svg|link=|alt=",
["saint barthelemy"] = "Flag of Saint Barthelemy (local).svg|border|link=|alt=flag",
["saint helena, ascension and tristan da cunha"] = "Flag of Saint Helena.svg|border|link=|alt=flag",
["saint kitts and nevis"] = "Flag of Saint Kitts and Nevis.svg|border|link=|alt=flag",
["saint lucia"] = "Flag of Saint Lucia.svg|border|link=|alt=flag",
["saint martin"] = "Flag of Saint Martin.png|border|link=|alt=flag",
["saint petersburg"] = "Flag of Saint Petersburg Russia.svg|alt=flag",
["saint pierre and miquelon"] = "Flag of Saint-Pierre and Miquelon.svg|border|link=|alt=flag",
["saint vincent and the grenadines"] = "Flag of Saint Vincent and the Grenadines.svg|border|link=|alt=flag",
["saints"] = "Gloriole blur.svg|link=|alt=",
["salad dressing"] = "Ranch dressing.jpg|link=|alt=",
["salmon"] = "Alaska salmon.jpg|link=|alt=",
["samoa"] = "Flag of Samoa.svg|border|link=|alt=flag",
["san antonio"] = "Coat of arms of San Antonio.svg|link=|alt=arms",
["san diego"] = "San Diego,California,USA. - panoramio (139).jpg|link=|alt=photo",
["san diego county"] = "Seal of San Diego County, California.png|link=|alt=seal",
["san diego–tijuana"] = "San Diego-Tijuana JPLLandsat.jpg|border|link=|alt=flag",
["sandwich"] = "Sandwich (1).jpg|link=|alt=",
["san francisco bay area"] = "SF From Marin Highlands3.jpg|border|link=|alt=",
["san francisco neighborhoods"] = "Columbus and Broadway (8219737166).jpg|link=|alt=",
["san luis potosí"] = "Flag of San Luis Potosi.svg|border|link=|alt=flag",
["san marino"] = "Flag of San Marino.svg|border|link=|alt=flag",
["santa barbara county"] = "Seal of Santa Barbara County, California.png|link=|alt=seal",
["santana"] = "Carlos Santana 2005.jpg|link=|alt=",
["santiago, chile"] = "Flag of Santiago de Chile.svg|alt=flag",
["são tomé and príncipe"] = "Flag of Sao Tome and Principe.svg|border|link=|alt=flag",
["são paulo"] = "Bandeira da cidade de São Paulo.svg|link=|alt=",
["salad"] = "Composed salad.jpg|link=|alt=",
["salads"] = "Composed salad.jpg|link=|alt=",
["salt"] = "Keukenzout (NaCl), onder de microscoop.jpg|link=|alt=",
["santiago"] = "Flag of Santiago de Chile.svg|alt=flag",
["sarajevo"] = "Flag of Sarajevo.svg|alt=flag",
["sarawak"] = "Flag of Sarawak.svg|border|link=|alt=flag",
["sasanian empire"] = "Derafsh Kaviani flag of the late Sassanid Empire.svg|border|link=|alt=flag",
["saskatchewan"] = "Flag of Saskatchewan.svg|border|link=|alt=flag",
["saskatchewan communities and neighbourhoods"] = "Flag-map of Saskatchewan.svg|link=|alt=map",
["saturn"] = "Saturn - April 25 2016 (24102807868).png|link=|alt=",
["saudi arabia"] = "Flag of Saudi Arabia.svg|border|link=|alt=flag",
["sausage"] = "Saucisses.svg|link=|alt=",
["sausages"] = "Saucisses.svg|link=|alt=",
["saxony"] = "Flag of Saxony.svg|border|link=|alt=flag",
["saxony-anhalt"] = "Flag of Saxony-Anhalt (state).svg|border|link=|alt=flag",
["schleswig-holstein"] = "Flag of Schleswig-Holstein (state).svg|border|link=|alt=flag",
["schools"] = "School.svg|link=|alt=icon",
["science"] = "Nuvola apps kalzium.svg|alt=icon",
["science and academia"] = "Rachel Carson w (cropped).jpg|link=|alt=photo",
["science fiction"] = "Sf-userbox.png|alt=icon",
["scientology"] = "Scientology e meter blue.jpg|alt=icon",
["scifi"] = "Sf-userbox.png|alt=icon",
["scotland"] = "Flag of Scotland.svg|border|link=|alt=flag",
["scottish islands"] = "ScottishIsles.jpg|link=|alt=map",
["scouting"] = "WikiProject Scouting fleur-de-lis dark.svg|alt=icon",
["sculpture"] = "Noun Project - Sculpture.svg|alt=",
["seafood"] = "Crab-icon.png|link=|alt=",
["seamounts"] = "Seamount.svg|link=|alt=",
["seattle"] = "SpaceNeedleTopClose.jpg|alt=icon",
["sega"] = "SEGA logo.svg|link=|alt=",
["senegal"] = "Flag of Senegal.svg|border|link=|alt=flag",
["selangor"] = "Flag of Selangor.svg|alt=flag",
["seoul"] = "Seal of Seoul.svg|link=|alt=seal",
["september 11 attacks"] = "Y24-Wtc-september-5.jpg|alt=icon",
["serbia"] = "Flag of Serbia.svg|border|link=|alt=flag",
["serbian cuisine"] = "Ćevapčići.jpg|link=|alt=",
["serer people"] = "Serer Royal War Drum (Jung-Jung). 19th Century. Jung-Jung From The Kingdom of Sine (in modern day Senegal).jpg|alt=icon",
["serer religion"] = "Five Pointed Star Lined.svg|link=|alt=",
["set theory"] = "Venn0001.svg|link=|alt=",
["seton hall university"] = "Shu logo.png|link=|alt=logo",
["seventh-day adventist church"] = "James and Ellen White.jpg|link=|alt=",
["severe weather"] = "Marquette, Kansas EF4 tornado on April 14, 2012.png|link=|alt=icon",
["sexuality"] = "Bisexuality symbol (bold, color).svg|alt=icon",
["sex work"] = "Umbrella-159361.svg|link=|alt=",
["seychelles"] = "Flag of Seychelles.svg|border|link=|alt=flag",
["sf"] = "Dragon-149393.svg|alt=icon",
["sfpeople"] = "Dragon-149393.svg|alt=icon",
["sfpubs"] = "Dragon-149393.svg|alt=icon",
["shakespeare"] = "Shakespeare (oval-cropped).png|link=|alt=",
["shakira"] = "S by shakira logo.png|alt=icon",
["shanghai"] = "Shanghainame.png|link=|alt=",
["shania twain"] = "Shania Twain Portrait.jpg|alt=icon",
["sharjah"] = "Flag of Sharjah.svg|border|link=|alt=flag",
["sharks"] = "Greyreefsharksmall2.jpg|alt=icon",
["shenzhen"] = "Shenzhen in Chinese.png|alt=Shenzhen",
["shia islam"] = "Ghadir logo.png|alt=icon",
["shinto"] = "Shinto torii icon vermillion.svg|link=|alt=",
["shreveport"] = "Shreveport-City-Flag.png|border|link=|alt=flag",
["shreya ghoshal"] = "Shreya at concert.jpg|alt=icon",
["shropshire"] = "Flag of Shropshire.svg|alt=flag|link=",
["siberia"] = "Kuznetsk Alatau 3.jpg|border|link=|alt=",
["sierra leone"] = "Flag of Sierra Leone.svg|border|link=|alt=flag",
["sikhism"] = "Khanda emblem.svg|link=|alt=",
["sikkim"] = "Seal of Sikkim color.png|link=|alt=seal",
["silent film"] = "Video-x-generic.svg|link=|alt=",
["silesia"] = "Silesia Inferior COA.svg|alt=icon",
["sinaloa"] = "Flag of Sinaloa.svg|border|link=|alt=flag",
["sindh"] = "Flag of Sindh.svg|border|link=|alt=flag",
["singapore"] = "Flag of Singapore.svg|border|link=|alt=flag",
["sint eustatius"] = "Flag of Sint Eustatius.svg|border|link=|alt=flag",
["sint maarten"] = "Flag of Sint Maarten.svg|border|link=|alt=flag",
["slavery"] = "IJzeren voetring voor gevangenen transparent background.png|border|link=|alt=icon",
["slipknot"] = "SlipknotProject.png|alt=icon",
["slovak republic"] = "Flag of Slovakia.svg|border|link=|alt=flag",
["slovakia"] = "Flag of Slovakia.svg|border|link=|alt=flag",
["slovenia"] = "Flag of Slovenia.svg|border|link=|alt=flag",
["sm entertainment"] = "SM Entertainment Logo.svg|link=|alt=",
["snakes"] = "Snake icon.svg|link=|alt=",
["snk"] = "SNK Playmore logo and wordmark.png|link=|alt=",
["snooker"] = "Snooker balls triangled.png|alt=icon",
["soap operas and telenovelas"] = "Drama-icon.svg|alt=icon",
["soccer in the united states"] = "Soccerball USA.png|link=|alt=",
["social and political philosophy"] = "P derecho.svg|link=|alt=",
["social movements"] = "Peace sign.svg|link=|alt=",
["social science"] = "P social sciences-lightblue.png|link=|alt=icon",
["social sciences"] = "DrustveneNauke.png|alt=icon",
["social welfare and social work"] = "Vista Login Manager Cropped.svg|alt=icon",
["socialism"] = "Red flag II.svg|alt=icon",
["society"] = "Social sciences.svg|alt=icon",
["sociology"] = "Logo sociology.svg|link=|alt=",
["soft drinks"] = "Soft Drink.svg|link=|alt=",
["software"] = "Crystal Clear device cdrom unmount.png|alt=icon",
["software testing"] = "Green bug and broom.svg|alt=icon",
["solar system"] = "Solar system.jpg|link=|alt=",
["solomon islands"] = "Flag of Solomon Islands.svg|border|link=|alt=flag",
["somalia"] = "Flag of Somalia.svg|border|link=|alt=flag",
["somaliland"] = "Flag of Somaliland.svg|border|link=|alt=flag",
["somerset"] = "Somerset shield.png|alt=icon",
["sonic"] = "Chaos emeralds.svg|alt=icon",
["sonora"] = "Flag of Sonora.svg|border|link=|alt=flag",
["sony"] = "Sony logo.svg|link=|alt=",
["sony playstation"] = "PS3-slim-console.png|link=|alt=",
["soup"] = "Shrimp and corn chowder.jpg|link=|alt=",
["soups"] = "Shrimp and corn chowder.jpg|link=|alt=",
["south africa"] = "Flag of South Africa.svg|border|link=|alt=flag",
["south america"] = "South America (orthographic projection).svg|link=|alt=map",
["south asia"] = "India 78.40398E 20.74980N.jpg|link=|alt=",
["south australia"] = "Flag of South Australia.svg|border|link=|alt=flag",
["south carolina"] = "Flag of South Carolina.svg|border|link=|alt=flag",
["south dakota"] = "Flag of South Dakota.svg|border|link=|alt=flag",
["south east england"] = "EnglandSouthEast.png|alt=icon",
["south georgia and the south sandwich islands"] = "Flag of South Georgia and the South Sandwich Islands.svg|border|link=|alt=flag",
["south korea"] = "Flag of South Korea.svg|border|link=|alt=flag",
["south park"] = "South Park sign logo.png|link=|alt=",
["south sudan"] = "Flag of South Sudan.svg|border|link=|alt=flag",
["southeast asia"] = "Location Southeast Asia.svg|link=|alt=",
["southern california"] = "USA California Southern location map.svg|link=|alt=map",
["southwest asia"] = "Southwest-Asia-map.PNG|link=|alt=",
["soviet union"] = "Flag of the Soviet Union.svg|border|link=|alt=flag",
["soy"] = "CSIRO ScienceImage 3273 Soybeans.jpg|link=|alt=",
["space"] = "Earth-moon.jpg|link=|alt=",
["spaceflight"] = "RocketSunIcon.svg|link=|alt=",
["spain"] = "Flag of Spain.svg|border|link=|alt=flag",
["spanish american wars of independence"] = "Red versus blue swords.svg|alt=icon",
["special operations"] = "APP-6 Special Operations Forces.svg|link=|alt=",
["speculative fiction"] = "Dragon-149393.svg|alt=icon",
["speculative fiction/fantasy"] = "Masked man.svg|link=|alt=icon",
["speculative fiction/horror"] = "Vampire Smiley.png|alt=icon",
["speculative fiction/people"] = "Dragon-149393.svg|alt=icon",
["speculative fiction/publications"] = "Dragon-149393.svg|alt=icon",
["spices"] = "Thymus vulgaris.jpg|link=|alt=icon",
["spirituality"] = "EndlessKnot03d.png|link=|alt=",
["spongebob squarepants"] = "WikiProject SpongeBob logo - Logo.svg|alt=icon",
["sports"] = "Sports icon.png|link=|alt=",
["sports and games"] = "Sports and games.png|alt=icon",
["sports in canada"] = "Flag shirt of Canada.png|alt=icon",
["sport of athletics"] = "Roman bronze copy of Myron’s Discobolos, 2nd century CE (Glyptothek Munich).jpg|link=|alt=",
["sri lanka"] = "Flag of Sri Lanka.svg|border|link=|alt=flag",
["sri lankan cuisine"] = "Kiribath (milk rice).jpg|link=|alt=",
["st. john's, newfoundland and labrador"] = "City of St. John's.jpg|link=|alt=",
["st. louis"] = "Flag of St. Louis, Missouri.svg|border|link=|alt=flag",
["staffordshire"] = "Staffordshire Flag.svg|border|link=|alt=flag",
["stamford"] = "Stamford town crest.png|link=|alt=crest",
["stanford university"] = "Stanford logo.png|link=|alt=logo",
["star"] = "He1523a.jpg|alt=icon",
["stars"] = "He1523a.jpg|alt=icon",
["star trek"] = "Delta-shield.svg|link=|alt=",
["star wars"] = "Lightsaber blue.svg|link=|alt=",
["state of georgia"] = "Flag of Georgia (U.S. state).svg|border|link=|alt=flag",
["state of mexico"] = "Flag of Mexico (state).png|border|link=|alt=flag",
["state university of new york"] = "SUNY brandmark.svg|link=|alt=brandmark",
["state university system of florida"] = "SUSF Locations.jpg|link=|alt=map",
["statistics"] = "Fisher iris versicolor sepalwidth.svg|alt=icon",
["statue of liberty"] = "FREEDOM FOR ALL!.jpg|alt=",
["steampunk"] = "Steampunk-falksen.jpg|alt=icon",
["stockholm"] = "Flag of Stockholm.svg|alt=flag",
["strategy games"] = "Chess.svg|alt=icon",
["strawberries"] = "FraiseFruitPhoto.jpg|link=|alt=",
["strawberry"] = "FraiseFruitPhoto.jpg|link=|alt=",
["street food"] = "Food Truck - The Noun Project.svg|link=|alt=",
["street foods"] = "Food Truck - The Noun Project.svg|link=|alt=",
["submarine"] = "Submarine.svg|alt=icon",
["submarines"] = "Submarine.svg|alt=icon",
["sudan"] = "Flag of Sudan.svg|border|link=|alt=flag",
["sufism"] = "Soefi symbool.gif|link=|alt=",
["super bowl"] = "Lombardi Trophy.png|link=|alt=",
["superfunds"] = "Superfund sites.svg|link=|alt=map",
["superhero fiction"] = "Question bubble thing.svg|link=|alt=",
["supermarket"] = "ShoppingCart.svg|link=|alt=",
["supermarkets"] = "ShoppingCart.svg|link=|alt=",
["supreme court of the united states"] = "Supreme Court.jpg|link=|alt=",
["surat"] = "Surat at night.JPG|link=|alt=photo",
["surfing"] = "Pictograms-nps-water-surfing.svg|link=|alt=",
["suriname"] = "Flag of Suriname.svg|border|link=|alt=flag",
["surrey"] = "EnglandSurrey.png|alt=icon",
["sushi"] = "Emojione 1F363.svg|border|link=|alt=",
["sustainability"] = "Nested sustainability-v2.svg|border|link=|alt=",
["sussex"] = "SussexBrit5.PNG|link=|alt=",
["sustainable development"] = "Sustainable development.svg|alt=icon",
["sweden"] = "Flag of Sweden.svg|border|link=|alt=flag",
["swimming"] = "Swimming pictogram.svg|link=|alt=",
["switzerland"] = "Flag of Switzerland.svg|border|link=|alt=flag",
["sydney"] = "Sydney COA.gif|alt=icon",
["syracuse, new york"] = "SyracuseSkyline01.JPG|link=|alt=",
["syria"] = "Flag of Syria.svg|border|link=|alt=flag",
["syriac christianity"] = "Bible and Pulpit, Mor Hananyo.jpg|alt=icon",
["syriac"] = "Syriac Sertâ book script.jpg|link=|alt=",
["syrian civil war"] = "Flag of Syria (2011 combined).svg|border|link=|alt=flag",
["systems"] = "Complex-adaptive-system.jpg|link=|alt=diagram",
["systems engineering initiative"] = "Systems Engineering Process II.gif|link=|alt=diagram",
["systems science"] = "Complex-adaptive-system.jpg|link=|alt=diagram"
}
a240880fd11e77e94cd6091361c41c9fdf8e85df
Template:Reflist
10
87
190
189
2022-09-04T15:24:51Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<templatestyles src="Reflist/styles.css" /><div class="reflist <!--
-->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!--
-->{{#switch:{{{liststyle|{{{group|}}}}}}|upper-alpha|upper-roman|lower-alpha|lower-greek|lower-roman=reflist-{{{liststyle|{{{group}}}}}}}} <!--
-->{{#if:{{{1|}}}|{{#iferror:{{#ifexpr: {{{1|1}}} > 1 }}||{{#switch:{{{1|}}}|1=|2=reflist-columns-2|#default=reflist-columns-3}} }}}}" <!-- end class
-->{{#if: {{{1|}}}<!-- start style -->
| {{#iferror: {{#ifexpr: {{{1|1}}} > 1 }} |style="column-width: {{{1}}};"}}
| {{#if: {{{colwidth|}}}|style="column-width: {{{colwidth}}};"}}
}}>
{{#tag:references|{{{refs|}}}|group={{{group|}}}|responsive={{#if:{{{1|}}}{{{colwidth|}}}|0|1}}}}</div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using reflist with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Reflist]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | colwidth | group | liststyle | refs }}<noinclude>
{{Documentation}}
</noinclude>
8c65cc88272db6c0f5cf2b49f84d3e460e60ee5f
Template:Reflist/styles.css
10
88
192
191
2022-09-04T15:24:51Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp|small=yes}} */
/* can we remove the font size declarations? .references gets a font-size in
* common.css that is always 90, and there is nothing else in reflist out in
* the wild. May affect column sizes.
*/
.reflist {
font-size: 90%; /* Default font-size */
margin-bottom: 0.5em;
list-style-type: decimal;
}
.reflist .references {
font-size: 100%; /* Reset font-size when nested in div.reflist */
margin-bottom: 0; /* Avoid double margin when nested in div.reflist */
list-style-type: inherit; /* Enable custom list style types */
}
/* columns-2 and columns-3 are legacy for "2 or more" column view from when the
* template was implemented with column-count.
*/
.reflist-columns-2 {
column-width: 30em;
}
.reflist-columns-3 {
column-width: 25em;
}
/* Reset top margin for lists embedded in columns */
.reflist-columns {
margin-top: 0.3em;
}
.reflist-columns ol {
margin-top: 0;
}
/* Avoid elements breaking between columns */
.reflist-columns li {
page-break-inside: avoid; /* Removed from CSS in favor of break-inside c. 2020 */
break-inside: avoid-column;
}
.reflist-upper-alpha {
list-style-type: upper-alpha;
}
.reflist-upper-roman {
list-style-type: upper-roman;
}
.reflist-lower-alpha {
list-style-type: lower-alpha;
}
.reflist-lower-greek {
list-style-type: lower-greek;
}
.reflist-lower-roman {
list-style-type: lower-roman;
}
531a26d48f0e7826c61f764cfb7d5fb200032c34
Template:Clear
10
89
194
193
2022-09-04T15:24:52Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>
{{documentation}}
</noinclude>
38bab3e3d7fbd3d6800d46556e60bc6bac494d72
Template:Authority control
10
90
196
195
2022-09-04T15:24:52Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:Authority control|authorityControl}}<noinclude>{{Documentation}}</noinclude><includeonly><noinclude>
</noinclude>{{#switch:{{NAMESPACE}}||{{ns:14}}=<noinclude> Only articles and categories.
</noinclude>{{#invoke:Check for unknown parameters|check|arts|state|extralist|ignoreblank=1|showblankpositional=1|unknown=[[Category:Pages using authority control with parameters|_VALUE_]]|preview=Page using [[Template:Authority control]] with "_VALUE_", please move this to Wikidata if possible}}
}}</includeonly>
e90b2d4067a752dad843f562fc9e4114bf560c8a
Module:Authority control
828
91
198
197
2022-09-04T15:24:53Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require('Module:No globals')
local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
--[[==========================================================================]]
--[[ Category functions ]]
--[[==========================================================================]]
local function addCat( cat )
if cat and cat ~= '' then return '[[Category:'..cat..']]'..p.redCatLink(cat) end
return ''
end
function p.getCatForId( id )
local cat = ''
if namespace == 0 then
cat = 'Articles with '..id..' identifiers'
end
return addCat(cat)
end
function p.redCatLink( cat ) --cat == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')
if cat and cat ~= '' and testcases == false and mw.title.new(cat, 14).exists == false then
return '[[Category:Pages with red-linked authority control categories]]'
end
return ''
end
function p.createRow( id, rawValues, link, links, withUid, specialCat, prefix)
local faultyCat = 'Articles with faulty '..(specialCat or id)..' identifiers'
if links then -- all links[] use withUid = false; no check needed
local row = ''
if prefix then
row = row..'*'..prefix
end
for i, l in ipairs( links ) do
if i == 1 and not prefix then row = row..'*'
else row = row..'\n**' end
if l then
row = row..'<span class="uid">'..l..'</span>'
else
row = row..'<span class="error">The '..id..' id '..rawValues[i]..' is not valid.</span>'..addCat(faultyCat)
end
end
return row..'\n'
elseif link then -- All IDs that have a prefix support multiple identifiers, so prefix is not needed
if withUid then
return '*<span class="nowrap"><span class="uid">'..link..'</span></span>\n'
end
return '*<span class="nowrap">'..link..'</span>\n'
end
return '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>'..addCat(faultyCat)..'\n'
end
--[[==========================================================================]]
--[[ Property formatting functions ]]
--[[==========================================================================]]
-- If a link has a suitable entry in the global inter-wiki prefix table at [[:m:Interwiki_map]],
-- please consider routing through this prefix rather than as external link URL.
-- This will ease future maintenance as necessary updates to the link can be centrally carried out there rather than by updating this module.
-- The "external link" icon would disappear for such entries.
function p.aagLink( id, label)
--P3372's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..(label or 'Auckland')..']'..p.getCatForId( 'AAG' )
end
function p.acmLink( id, label )
--P864's format regex: \d{11} (e.g. 12345678901)
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://dl.acm.org/profile/'..id..' '..(label or 'Association for Computing Machinery')..']'..p.getCatForId( 'ACM-DL' )
end
function p.adbLink( id, label )
--P1907's format regex: [a-z][-a-z]+-([1-3]\d|[1-9])\d{0,3} (e.g. barton-sir-edmund-toby-71)
if not id:match( '^[a-z][-a-z]+-[1-3]%d%d?%d?%d?$' ) and
not id:match( '^[a-z][-a-z]+-[1-9]%d?%d?%d?$' ) then
return false
end
return '[http://adb.anu.edu.au/biography/'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'ADB' )
end
function p.admiraltyLink(id,label)
--P3562's format regex: [A-Q]\d{4}(\.\d+)? (e.g. D1204.1)
if not id:match('^[A-Q]%d%d%d%d$') and
not id:match('^[A-Q]%d%d%d%d%.%d+$') then
return false
end
return id..p.getCatForId( 'admiralty' )
end
function p.agsaLink( id, label )
--P6804's format regex: [1-9]\d* (e.g. 3625)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..(label or 'South Australia')..']'..p.getCatForId( 'AGSA' )
end
function p.ARLHSLink(id,label)
--P2980's format regex: [A-Z]{3}\d{3,4}[A-Z]?| e.g. LAT023
if not id:match('^[A-Z][A-Z][A-Z]%d%d%d%d?[A-Z]?$') then
return false
end
return '[http://wlol.arlhs.com/lighthouse/'..id..'.html '..(label or 'ARLHS')..']'..p.getCatForId( 'ARLHS' )
end
function p.autoresuyLink( id, label )
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
if not id:match( '^[1-9]%d?%d?%d?%d?$' ) then
return false
end
return '[https://autores.uy/autor/'..id..' '..(label or 'Uruguay')..']'..p.getCatForId( 'autores.uy' )
end
function p.awrLink( id, label )
--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
return false
end
return '[http://www.womenaustralia.info/biogs/'..id..'.htm '..(label or 'Australian Women\'s Register')..']'..p.getCatForId( 'AWR' )
end
function p.bibsysLink( id, label )
--P1015's format regex: [1-9]\d* or [1-9](\d{0,8}|\d{12}) (e.g. 1234567890123)
--TODO: follow up @ [[d:Property talk:P1015#Discrepancy between the 2 regex constraints]] or escalate/investigate
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..(label or 'Norway')..']'..p.getCatForId( 'BIBSYS' )
end
function p.bildLink( id, label )
--P2092's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.bildindex.de/document/obj'..id..' '..(label or 'Bildindex (Germany)')..']'..p.getCatForId( 'Bildindex' )
end
function p.bncLink( id, label )
--P1890's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..(label or 'Chile')..']'..p.getCatForId( 'BNC' )
end
function p.bneLink( id, label )
--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
not id:match( '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..(label or 'Spain')..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019
end
function p.bnfLink( id, label )
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
return false
end
--Add cb prefix if it has been removed
if not id:match( '^cb.+$' ) then
id = 'cb'..id
end
return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..(label or 'France')..'] [https://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )
end
function p.bnmmLink( id, label )
--P3788's format regex: \d{9} (e.g. 000024044)
if id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return '[https://catalogo.bn.gov.ar/F/?func=direct&local_base=BNA10&doc_number='..id..' '..(label or 'Argentina')..']'..p.getCatForId( 'BNMM' )
else
return false
end
end
function p.botanistLink( id, label )
--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(Ma?c)?[\p{Lu}bht]?C?['\p{Ll}]*)*\.? ?f?\.? (e.g. L.)
--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing
return false
end
id = id:gsub(' +', '%%20')
return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id..' '..(label or 'International Plant Names Index')..']'..p.getCatForId( 'Botanist' )
end
function p.bpnLink( id, label )
--P651's format regex: \d{6,8} (e.g. 00123456)
if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
not id:match( '^0?0?%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end
function p.canticLink( id, label )
--P1273's format regex: a\d{7}[0-9x] (e.g. a10640745)
if not id:match( '^a%d%d%d%d%d%d%d[%dx]$' ) then
return false
end
return '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..(label or 'Catalonia')..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end
function p.canticnLink( id, label )
--P9984's format regex: 981(0|1)\d{9}06706 (e.g. 981058515460906706)
if not id:match( '^981[0-1]%d%d%d%d%d%d%d%d%d06706$' ) then
return false
end
return '[https://cantic.bnc.cat/registre/'..id..' '..(label or 'Catalonia')..']'..p.getCatForId( 'CANTICN' )
end
function p.ccgLink( id, label )
--P3920's format regex: ([NAIP])?[1-9]\d*(\.\d+)? (e.g. A1761)
if not id:match( '^[NAIP]?[1-9]%d*$' ) and
not id:match( '^[NAIP]?[1-9]%d*%.%d+$' ) then
return false
end
return id..p.getCatForId( 'CCG' )
end
function p.ciniiLink( id, label )
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..(label or 'CiNii (Japan)')..']'..p.getCatForId( 'CINII' )
end
function p.cwgcLink( id, label )
--P1908's format regex: [1-9]\d* (e.g. 75228351)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://www.cwgc.org/find-war-dead/casualty/'..id..'/ '..(label or 'Commonwealth War Graves Commission')..']'..p.getCatForId( 'CWGC' )
end
function p.emuLink( id, label )
--P4613's format regex: \d{1,6} (e.g. 15409 (or 015409))
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://esu.com.ua/search_articles.php?id='..id..' '..(label or 'Ukraine')..']'..p.getCatForId( 'EMU' )
end
function p.daaoLink( id, label )
--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
if not id:match( '^[a-z%-]+%d*$' ) then
return false
end
return '[https://www.daao.org.au/bio/'..id..' '..(label or 'Australian Artists')..']'..p.getCatForId( 'DAAO' )
end
function p.dblpLink( id, label )
--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
if not id:match( '^%d%d%d?/%d+$' ) and
not id:match( '^%d%d%d?/%d+%-%d+$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
return false
end
return '[https://dblp.org/pid/'..id..' '..(label or 'DBLP (computer science)')..']'..p.getCatForId( 'DBLP' )
end
function p.dibLink( id, label )
--P6829's format regex: 0[01]\d{4}(\.[A-D])? (e.g. 001953)
if not id:match( '^0[01]%d%d%d%d%.?[A-D]?$' ) then
return false
end
return '[https://dib.cambridge.org/viewReadPage.do?articleId='..id..' '..(label or 'Ireland')..']'..p.getCatForId( 'DIB' )
end
function p.dsiLink( id, label )
--P2349's format regex: [1-9]\d* (e.g. 1538)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..(label or 'Scientific illustrators')..']'..p.getCatForId( 'DSI' )
end
function p.dtbioLink( id, label )
--P7902's format regex: 1[0-9]{7,8}[0-9X] (e.g. 118554700)
if not id:match( '^1[0-9]%d%d%d%d%d%d%d?[0-9X]$' ) then
return false
end
return '[https://www.deutsche-biographie.de/pnd'..id..'.html?language=en '..(label or 'Germany')..']'..p.getCatForId( 'DTBIO' )
end
function p.fastLink( id, label )
--P2163's format regex: [1-9]\d{0,7} (e.g. 1916996)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://id.worldcat.org/fast/'..id..'/ '..(label or 'Faceted Application of Subject Terminology')..']'..p.getCatForId( 'FAST' )
end
function p.fnzaLink( id, label )
--P6792's format regex: [1-9]\d* (e.g. 9785)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://findnzartists.org.nz/artist/'..id..'/ '..(label or 'New Zealand Artists')..']'..p.getCatForId( 'FNZA' )
end
function p.gndLink( id, label )
--P227's format regex: 1[012]?\d{7}[0-9X]|[47]\d{6}-\d|[1-9]\d{0,7}-[0-9X]|3\d{7}[0-9X] (e.g. 4079154-3)
if not id:match( '^1[012]?%d%d%d%d%d%d%d[0-9X]$' ) and
not id:match( '^[47]%d%d%d%d%d%d%-%d$' ) and
not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
not id:match( '^3%d%d%d%d%d%d%d[0-9X]$' ) then
return false
end
return '[https://d-nb.info/gnd/'..id..' '..(label or 'Germany')..']'..p.getCatForId( 'GND' )
end
function p.googleLink( id, label )
--P1960's format regex: [-_0-9A-Za-z]{12} (e.g. CUO0vDcAAAAJ)
if not id:match( '^[%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u]$' ) then
return false
end
return '[https://scholar.google.com/citations?user='..id..' '..(label or 'Google Scholar')..']'..p.getCatForId( 'Google Scholar' )
end
function p.hdsLink( id, label )
--P902's format regex: \d{6} (e.g. 050123)
if not id:match( '^%d%d%d%d%d%d$' ) then
return false
end
return '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..(label or 'Historical Dictionary of Switzerland')..']'..p.getCatForId( 'HDS' )
end
function p.iaafLink( id, label )
--P1146's format regex: [0-9][0-9]* (e.g. 012)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.iaaf.org/athletes/_/'..id..' '..(label or 'World Athletics')..']'..p.getCatForId( 'IAAF' )
end
function p.iccuLink( id, label )
--P396's format regex: \D{2}[A-Z0-3]V\d{6} (e.g. CFIV000163)
if not id:match( '^%u%u[%u0-3]V%d%d%d%d%d%d$' ) then --legacy: %u used here instead of %D (but the faulty ID cat is empty, out of ~12k uses)
return false
end
return '[https://opac.sbn.it/nome/'..id..' '..(label or 'Italy')..']'..p.getCatForId( 'ICCU' )
end
function p.iciaLink( id, label )
--P1736's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..(label or 'ICIA (Israel)')..']'..p.getCatForId( 'ICIA' )
end
function p.ieuLink( id, label )
--P9070's format regex: [A-Z]\\[A-Z]\\[A-Za-z0-9]+ (e.g. K\Y\Kyiv)
if not id:match( '^[A-Z]\\[A-Z]\\%w+$' ) then
return false
end
return '[http://www.encyclopediaofukraine.com/display.asp?linkpath=pages\\'..id..' '..(label or 'Internet Encyclopedia of Ukraine')..']'..p.getCatForId( 'IEU' )
end
function p.isniLink( id, label )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return '[https://isni.org/isni/'..id..' '..(label or 'ISNI')..']'..p.getCatForId( 'ISNI' )
end
function p.j9uLink( id, label )
--P8189's format regex: 9870(0|1)\d{8}05171 (e.g. 987007305652505171)
if not id:match( '^9870[0-1]%d%d%d%d%d%d%d%d05171$' ) then
return false
end
return '[http://uli.nli.org.il/F/?func=find-b&local_base=NLX10&find_code=UID&request='..id..' '..(label or 'Israel')..']'..p.getCatForId( 'J9U' )
end
function p.jocondeLink( id, label )
--P347's format regex: [\-0-9A-Za-z]{11} (e.g. 12345678901)
local regex = '^'..string.rep('[%-0-9A-Za-z]', 11)..'$'
if not id:match( regex ) then
return false
end
return '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..(label or 'Joconde (France)')..']'..p.getCatForId( 'Joconde' )
end
function p.kulturnavLink( id, label )
--P1248's format regex: [0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[http://kulturnav.org/'..id..' '..(label or 'KulturNav (Norway)')..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end
function p.lccnLink( id, label )
local parts = p.splitLccn( id ) --e.g. n78039510
if not parts then
return false
end
local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
id = parts[1] .. parts[2] .. p.append( parts[3], '0', 6 )
return '[https://id.loc.gov/authorities/'..lccnType..'/'..id..' '..(label or 'United States')..']'..p.getCatForId( 'LCCN' )
end
function p.lirLink( id, label )
--P886's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..(label or 'Lexicon Istoric Retic (Switzerland)')..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end
function p.lnbLink( id, label )
--P1368's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..(label or 'Latvia')..']'..p.getCatForId( 'LNB' )
end
function p.marinaMilitareLink( id, label )
--P3863's format regex: [1-9]\d* (e.g. 3856)
if id:match( '^[1-9]%d*$' ) then
return '[http://www.marina.difesa.it/cosa-facciamo/per-la-difesa-sicurezza/fari/Pagine/'..id..'.aspx '..(label or 'Italy')..']'..p.getCatForId( 'Marina Militare' )
else
return false
end
end
function p.mathsnLink( id, label )
--P4955's format regex: [1-9]\d{4,6} (e.g. 175270)
if not id:match( '^[1-9]%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://mathscinet.ams.org/mathscinet/MRAuthorID/'..id..' '..(label or 'MathSciNet')..']'..p.getCatForId( 'MATHSN' )
end
function p.mbaLink( id, label )
--P434's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/artist/'..id
local cat = p.getCatForId( 'MusicBrainz' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBA (identifier)|MusicBrainz]] ['..url..' artist]'..cat
end
end
function p.mbareaLink( id, label )
--P982's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/area/'..id
local cat = p.getCatForId( 'MusicBrainz area' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBAREA (identifier)|MusicBrainz]] ['..url..' area]'..cat
end
end
function p.mbiLink( id, label )
--P1330's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/instrument/'..id
local cat = p.getCatForId( 'MusicBrainz instrument' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBI (identifier)|MusicBrainz]] ['..url..' instrument]'..cat
end
end
function p.mblLink( id, label )
--P966's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/label/'..id
local cat = p.getCatForId( 'MusicBrainz label' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBL (identifier)|MusicBrainz]] ['..url..' label]'..cat
end
end
function p.mbpLink( id, label )
--P1004's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/place/'..id
local cat = p.getCatForId( 'MusicBrainz place' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBP (identifier)|MusicBrainz]] ['..url..' place]'..cat
end
end
function p.mbrgLink( id, label )
--P436's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/release-group/'..id
local cat = p.getCatForId( 'MusicBrainz release group' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBRG (identifier)|MusicBrainz]] ['..url..' release group]'..cat
end
end
function p.mbsLink( id, label )
--P1407's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/series/'..id
local cat = p.getCatForId( 'MusicBrainz series' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBS (identifier)|MusicBrainz]] ['..url..' series]'..cat
end
end
function p.mbwLink( id, label )
--P435's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
local url = 'https://musicbrainz.org/work/'..id
local cat = p.getCatForId( 'MusicBrainz work' )--special cat name
if label then
return '['..url..' '..label..']'..cat
else
return '[[MBW (identifier)|MusicBrainz]] ['..url..' work]'..cat
end
end
function p.mgpLink( id, label )
--P549's format regex: \d{1,6} (e.g. 123456)
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://www.mathgenealogy.org/id.php?id='..id..' '..(label or 'Mathematics Genealogy Project')..']'..p.getCatForId( 'MGP' )
end
function p.mtLink( id, label )
--P3601's format regex: \d{10} (e.g. 1000004707)
if id:match( '^%d%d%d%d%d%d%d%d%d%d$' ) then
return '[https://www.marinetraffic.com/en/ais/details/lights/'..id..' '..(label or 'MarineTraffic')..']'..p.getCatForId( 'MarineTraffic' )
else
return false
end
end
function p.naraLink( id, label )
--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://catalog.archives.gov/id/'..id..' '..(label or 'National Archives (US)')..']'..p.getCatForId( 'NARA' )
end
function p.nclLink( id, label )
--P1048's format regex: \d+ (e.g. 1081436)
if not id:match( '^%d+$' ) then
return false
end
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..(label or 'Taiwan')..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019
end
function p.ndlLink( id, label )
--P349's format regex: 0?\d{8} (e.g. 012345678)
if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..(label or 'Japan')..']'..p.getCatForId( 'NDL' )
end
function p.ngaLink(id,label)
--P3563's format rgex: 11[0-6]-\d+(\.\d+)? (e.g. 114-7721.2)
if not id:match('^11[0-6]%-%d+%.?%d*$') then
return false
end
return '[https://wikidata-externalid-url.toolforge.org/?url=https%3A%2F%2Fmsi.nga.mil%2FqueryResults%3Fpublications%2Fngalol%2Flights-buoys%3Fvolume%3D%251%26featureNumber%3D%252%26includeRemovals%3Dfalse%26output%3Dhtml&exp=(%5Cd%7B3%7D)-(.*)&id='..id..' '..(label or 'NGA')..']'..p.getCatForId( 'NGA' )
end
function p.ngvLink( id, label )
--P2041's format regex: \d+ (e.g. 12354)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..(label or 'Victoria')..']'..p.getCatForId( 'NGV' )
end
function p.nkcLink( id, label )
--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
if not id:match( '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..(label or 'Czech Republic')..']'..p.getCatForId( 'NKC' )
end
function p.nlaLink( id, label )
--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://nla.gov.au/anbd.aut-an'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'NLA' )
end
function p.nlgLink( id, label )
--P3348's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://data.nlg.gr/resource/authority/record'..id..' '..(label or 'Greece')..']'..p.getCatForId( 'NLG' )
end
function p.nlkLink( id, label )
--P5034's format regex: (KAB|KAC|KSH)([0-9]{4}|[0-9]{4}[a-zA-Z])[0-9]{4,6} (e.g. KAC201501465)
if not id:match( '^KAB%d%d%d%d%a?%d%d%d%d%d?%d?$' ) and
not id:match( '^KAC%d%d%d%d%a?%d%d%d%d%d?%d?$' ) and
not id:match( '^KSH%d%d%d%d%a?%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://lod.nl.go.kr/resource/'..id..' '..(label or 'Korea')..']'..p.getCatForId( 'NLK' )
end
function p.nlpLink( id, label )
--P1695's format regex: 9810[0-9]\d* or A[0-9]{7}[0-9X] (e.g. 9810123456789012345 or A10414836)
if not id:match( '^9810%d+$' ) and
not id:match( '^A%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'NLP' )
end
function p.nlrLink( id, label )
--P1003's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://aleph.bibnat.ro:8991/F/?func=direct&local_base=NLR10&doc_number='..id..' '..(label or 'Romania')..']'..p.getCatForId( 'NLR' )
end
function p.nskLink( id, label )
--P1375's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..(label or 'Croatia')..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end
function p.ntaLink( id, label )
--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)
if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[http://data.bibliotheken.nl/id/thes/p'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'NTA' )
end
function p.orcidLink( id, label )
id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483
if not id then
return false
end
id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
return '[https://orcid.org/'..id..' '..(label or 'ORCID')..']'..p.getCatForId( 'ORCID' )
end
function p.picLink( id, label )
--P2750's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://pic.nypl.org/constituents/'..id..' '..(label or 'Photographers\' Identities')..']'..p.getCatForId( 'PIC' )
end
function p.plwabnLink( id, label )
--P7293's format regex: 981[0-9]{8}05606 (e.g. 9810696457305606)
if not id:match( '^981%d%d%d%d%d%d%d%d05606*$' ) then
return false
end
return '[http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=1&NU=1&IM=4&WI='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'PLWABN' )
end
function p.publonsLink( id, label )
--P3829's format regex: \d+ (e.g. 654601)
if not id:match( '^%d+$' ) then
return false
end
return '[https://publons.com/author/'..id..'/ '..(label or 'Publons (researchers)')..']'..p.getCatForId( 'Publons' )
end
function p.ridLink( id, label )
--P1053's format regex: [A-Z]{1,3}-\d{4}-(19|20)\d\d (e.g. AAS-5150-2020)
if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-19%d%d$' ) and
not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20%d%d$' ) then
return false
end
return '[https://www.researcherid.com/rid/'..id..' '..(label or 'ResearcherID')..']'..p.getCatForId( 'RID' )
end
function p.rismLink( id, label )
--P5504's format regex: (pe|ks)?\[1-9]d* (e.g. pe30006410)
if not id:match( '^pe[1-9]%d*$' ) and --99% start with 'pe'
not id:match( '^ks[1-9]%d*$' ) and
not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://opac.rism.info/search?id='..id..' '..(label or 'RISM (France)')..']'..p.getCatForId( 'RISM' )
end
function p.reroLink( id, label )
--P3065's format regex: 0[1-2]-[A-Z0-9]{1,10} (e.g. 02-A012345678)
if not id:match( '^0[1-2]%-[A-Z%d][A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?$' ) then
return false
end
return '[http://data.rero.ch/'..id..' '..(label or 'RERO (Switzerland)')..']'..p.getCatForId( 'RERO' )
end
function p.rkdartistsLink( id, label )
--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/en/explore/artists/'..id..' '..(label or 'RKD Artists (Netherlands)')..']'..p.getCatForId( 'RKDartists' )
end
function p.rkdidLink( id, label )
--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/nl/explore/images/'..id..' '..(label or 'RKD ID (Netherlands)')..']'..p.getCatForId( 'RKDID' )
end
function p.rslLink( id, label )
--P947's format regex: \d{1,9} (e.g. 123456789)
if not id:match( '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..(label or 'Russia')..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019
end
function p.scopusLink( id, label )
--P1153's format regex: [1-9]\d{9,10} (e.g. 35247902700)
if not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d?$' ) then
return false
end
return '[https://www.scopus.com/authid/detail.uri?authorId='..id..' '..(label or 'Scopus author')..']'..p.getCatForId( 'Scopus' )
end
function p.selibrLink( id, label )
--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
if not id:match( '^[1-9]%d%d%d%d%d?$' ) then
return false
end
return '[https://libris.kb.se/auth/'..id..' '..(label or 'Sweden')..']'..p.getCatForId( 'SELIBR' )
end
function p.sikartLink( id, label )
--P781's format regex: \d{7,9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) then
return false
end
return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..(label or 'SIKART (Switzerland)')..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019
end
function p.snacLink( id, label )
--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
return false
end
return '[https://snaccooperative.org/ark:/99166/'..id..' '..(label or 'Social Networks and Archival Context')..']'..p.getCatForId( 'SNAC-ID' )
end
function p.sudocLink( id, label )
--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)
if not id:match( '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'
return false
end
return '[https://www.idref.fr/'..id..' '..(label or 'SUDOC (France)')..']'..p.getCatForId( 'SUDOC' )
end
function p.ta98Link( id, label )
--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
return false
end
local longurl = '[http://tools.wmflabs.org/wikidata-externalid-url/?p=1323&url_prefix=https:%2F%2Fwww.unifr.ch%2Fifaa%2FPublic%2FEntryPage%2FTA98%20Tree%2FEntity%20TA98%20EN%2F&url_suffix=%20Entity%20TA98%20EN.htm&id='
return longurl..id..' '..(label or 'Terminologia Anatomica')..']'..p.getCatForId( 'TA98' )
end
function p.tdviaLink( id, label )
--P7314's format regex: [0-9a-z/-]+] (e.g. barkan-omer-lutfi)
if not id:match( '^[%d%l/-]+$' ) then
return false
end
return '[https://islamansiklopedisi.org.tr/'..id..' '..(label or 'İslâm Ansiklopedisi')..']'..p.getCatForId( 'TDVİA' )
end
function p.tepapaLink( id, label )
--P3544's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://collections.tepapa.govt.nz/agent/'..id..' '..(label or 'Te Papa (New Zealand)')..']'..p.getCatForId( 'TePapa' )
end
function p.tlsLink( id, label )
id = id:gsub(' +', '_')
--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*\/–&]{3,89} (e.g. Abcd)
--Mediawiki page title partial URL so consider validation with mw.title or "[^#<>%[%] {|}]"
local class = "[%w_',%.%-%(%)%*%/–&]"
local idlen = mw.ustring.len (id)
if idlen < 4 or idlen > 90 then
return false
end
local regex = '^%u'..string.rep(class, idlen - 1)..'$'
if not mw.ustring.match( id, regex ) then
return false
end
return '[http://tls.theaterwissenschaft.ch/wiki/'..id..' '..(label or 'Theaterlexikon (Switzerland)')..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019
end
function p.troveLink( id, label )
--P1315's format regex: [1-9]\d{5,7} (e.g. 12345678)
if not id:match( '^[1-9]%d%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://trove.nla.gov.au/people/'..id..' '..(label or 'Trove (Australia)')..']'..p.getCatForId( 'Trove' )
end
function p.ukparlLink( id, label )
--P6213's format regex: [a-zA-Z\d]{8} (e.g. AQUupyiR)
if not id:match( '^[a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d]$' ) then
return false
end
return '[https://id.parliament.uk/'..id..' '..(label or 'UK Parliament')..']'..p.getCatForId( 'UKPARL' )
end
function p.ulanLink( id, label )
--P245's format regex: 500\d{6} (e.g. 500123456)
if not id:match( '^500%d%d%d%d%d%d$' ) then
return false
end
return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..(label or 'Artist Names (Getty)')..']'..p.getCatForId( 'ULAN' )
end
function p.uscgLink( id, label )
--P3723's format regex: [1-7]-\d{1,5}(.[1-9])? (e.g. 6-0695)
if not id:match( '^[1-7]%-%d%d?%d?%d?%d?$' ) and
not id:match( '^[1-7]%-%d%d?%d?%d?%d?%.%d*[1-9]$' ) then
return false
end
return '[[USCG (identifier)|USCG]] ([https://www.navcen.uscg.gov/pdf/lightlists/LightList%20V'..mw.ustring.sub(id,1,1)..'.pdf '..id..'])'..p.getCatForId( 'USCG' )
end
function p.uscongressLink( id, label )
--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
if not id:match( '^[A-Z]00[01]%d%d%d$' ) then
return false
end
return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..(label or 'US Congress')..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019
end
function p.vcbaLink( id, label )
--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)
if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
id = id:gsub('\/', '_')
return '[https://opac.vatlib.it/auth/detail/'..id..' '..(label or 'Vatican')..']'..p.getCatForId( 'VcBA' )
end
function p.viafLink( id, label )
--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)
if not id:match( '^[1-9]%d%d?%d?%d?%d?%d?%d?%d?$' ) and
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d?%d?%d?$' ) then
return false
end
-- If the "VIAF" entry at [[:m:Interwiki map]] would resolve to "https://viaf.org/viaf/$1" (rather than "http://viaf.org/viaf/$1", as it currently still does),
-- then the code below could change from '[https://viaf.org/viaf/'..id..' '..id..']' to '[[:VIAF:'..id..'|'..id..']]'.
return '[https://viaf.org/viaf/'..id..' '..(label or 'VIAF')..']'..p.getCatForId( 'VIAF' )
end
function p.worldcatidLink( id, label )
--P7859's format regex: viaf-\d+|lccn-n[a-z]?[0-9\-]+|n[cps]-.+ (e.g. viaf-100181709, lccn-n78-95332, np-verbeck,%20william$1861)
if not id:match( '^viaf%-%d+$' ) and
not id:match( '^lccn%-n[a-z]?[0-9%-]+$' ) and
not id:match( '^n[cps]%-.+$' ) then
return false
end
return '[https://www.worldcat.org/identities/'..mw.uri.encode(id, 'PATH')..'/ '..(label or 'WorldCat')..']'..p.getCatForId( 'WORLDCATID' )
end
function p.zbmathLink( id, label )
--P1556's format regex: [a-z][a-z\-]*(\.[a-z][a-z\-]*)?(\.[0-9]*)? (e.g. turing.alan-m)
local ps = {'%l[%l%-]*', '%.%l[%l%-]*', '%.%d*'}
if not id:match( '^'..ps[1]..'$' ) and -- prefix with no capture options
not id:match( '^'..ps[1]..ps[2]..'$' ) and -- prefix with first capture option
not id:match( '^'..ps[1]..ps[3]..'$' ) and -- prefix with second capture option
not id:match( '^'..ps[1]..ps[2]..ps[3]..'$' ) then -- prefix and both capture options
return false
end
return '[https://zbmath.org/authors/?q=ai:'..id..' '..(label or 'zbMATH')..']'..p.getCatForId( 'ZBMATH' )
end
--[[=========================== Helper functions =============================]]
function p.append(str, c, length)
while str:len() < length do
str = c..str
end
return str
end
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
function p.getIsniCheckDigit( isni )
local total = 0
for i = 1, 15 do
local digit = isni:byte( i ) - 48 --Get integer value
total = (total + digit) * 2
end
local remainder = total % 11
local result = (12 - remainder) % 11
if result == 10 then
return 'X'
end
return tostring( result )
end
--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function p.validateIsni( id )
--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)
--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)
id = id:gsub( '[ %-]', '' ):upper()
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
return false
end
return id
end
function p.splitLccn( id )
--P244's format regex: (n|nb|nr|no|ns|sh)([4-9][0-9]|00|20[0-1][0-9])[0-9]{6} (e.g. n78039510)
if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
end
if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
return mw.text.split( id, '/' )
end
return false
end
--[[==========================================================================]]
--[[ Wikidata & documentation functions ]]
--[[==========================================================================]]
function p.getIdsFromWikidata( itemId, property )
local ids = {}
if not mw.wikibase then
return ids
end
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
table.insert( ids, statement.mainsnak.datavalue.value )
end
end
end
return ids
end
function p.checkcat( category,label )
local ret='[[:Category:'..category..'|'..label..']]'
if mw.title.new(category, 14).exists == false then
ret = ret..' <span class="plainlinks" style="font-size:85%;">[['..tostring(mw.uri.fullUrl('Category:'..category,'action=edit&preload=Template:Authority_control/preload'))..' create]]</span>'
end
return ret
end
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
function p.docConfTable( frame )
local wikiTable = '<table class="wikitable sortable">'..
'<tr><th rowspan=2>Parameter</th>'..
'<th rowspan=2>Section</th>'..
'<th rowspan=2>Appears as</th>'..
'<th rowspan=2 data-sort-type=number>Wikidata property</th>'..
'<th colspan=2>Tracking categories and page counts</th></tr>'..
'<tr><th>[[:Category:Articles with authority control information|Articles]]</th>'..
'<th>[[:Category:Articles with faulty authority control information|Faulty IDs]]</th></tr>'
local lang = mw.getContentLanguage()
local a, f, P = 0, 0, 0 --cumulative sums
for _, conf in pairs( p.conf ) do
local param, pid, section = conf[1], conf[2], conf[4]
local appearsAs
if conf.prefix then
appearsAs = conf.prefix
else
appearsAs = conf[3](conf[5])
end
local link = conf.link or param..' (identifier)'
local category = conf.category or param
local args = { id = 'f', pid }
local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }
--cats
local articleCat = 'Articles with '..category..' identifiers'
local faultyCat = 'Articles with faulty '..category..' identifiers'
--counts
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
local faultyCount = lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )
--calcs
P = P + 1 --property count
a = a + lang:parseFormattedNumber(articleCount)
f = f + lang:parseFormattedNumber(faultyCount)
--concat
wikiTable = wikiTable..'<tr><td>[['..link..'|'..param..']]</td>'..
'<td>'..section..'</td>'..
'<td>'..appearsAs..'</td>'..
'<td data-sort-value='..pid..'>'..wpl..'</td>'..
'<td style="text-align: right;">'..p.checkcat(articleCat,articleCount)..'</td>'..
'<td style="text-align: right;">'..p.checkcat(faultyCat,faultyCount)..'</td></tr>'
end
--append derivative WorldCat cats
local wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' }
for _, w in pairs(wcd) do
local articleCat = 'Articles with '..w..' identifiers'
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
local appearsAs
if w == 'WorldCat-LCCN' then
appearsAs = '[https://www.worldcat.org/identities/lccn-n79-113947 WorldCat (via Library of Congress)]'
else
appearsAs = '[https://www.worldcat.org/identities/containsVIAFID/12345789 WorldCat (via VIAF)]'
end
a = a + lang:parseFormattedNumber(articleCount)
wikiTable = wikiTable..'<tr><td>-</td>'..
'<td>General</td>'..
'<td>'..appearsAs..'</td>'..
'<td data-sort-value='..w..'>—</td>'..
'<td style="text-align: right;">[[:Category:'..articleCat..'|'..articleCount..']]</td>'..
'<td style="text-align: right;">—</td></tr>'
end
--append sums
wikiTable = wikiTable..'<tr><th style="text-align: right;" colspan=3>Totals</th>'..
'<th style="text-align: right;">'..lang:formatNum(P)..'</th>'..
'<th style="text-align: right;">'..lang:formatNum(a)..'</th>'..
'<th style="text-align: right;">'..lang:formatNum(f)..'</th></tr></table>'
return require('Module:Suppress categories').main(wikiTable)
end
--[[==========================================================================]]
--[[ Configuration ]]
--[[==========================================================================]]
-- Please use "<parameter> (identifier)" redirects rather than linking directly to the target page.
-- This reduces clutter in "What links here" on both the redirect and the target,
-- and improves reverse lookup of articles where a manifestation of each identifier is used.
-- p.conf table basic format: { 'parameter name', propertyId # in Wikidata, formatting/validation function, section, example ID for documentation }
-- p.conf table optional named parameters:
-- link: to override the link in the documentation (defaults to "<parameter> (identifer)")
-- category: to override the ID in category names (defaults to "... with <parameter> identifiers")
-- prefix: to include a prefix (usually a wikilink explaining what the identifier is) before the external link itself
p.conf = {
{ 'AAG', 3372, p.aagLink, 'Art galleries and museums', '1' },
{ 'ACM-DL', 864, p.acmLink, 'Scientific databases', '12345678901', link = 'ACM DL (identifier)' },
{ 'ADB', 1907, p.adbLink,'Biographical dictionaries', 'barton-sir-edmund-toby-71' },
{ 'admiralty', 3562, p.admiraltyLink, 'Lighthouse identifiers', 'D1204.1', prefix='[[Admiralty number|Admiralty]]'},
{ 'AGSA', 6804, p.agsaLink, 'Art galleries and museums', '3625' },
{ 'ARLHS', 2980, p.ARLHSLink, 'Lighthouse identifiers', 'LAT023'},
{ 'autores.uy', 2558, p.autoresuyLink, 'Biographical dictionaries', '12345' },
{ 'AWR', 4186, p.awrLink, 'Biographical dictionaries', 'PR00768b' },
{ 'BIBSYS', 1015, p.bibsysLink, 'National libraries', '1234567890123' },
{ 'Bildindex', 2092, p.bildLink, 'Art research institutes', '1' },
{ 'BNC', 1890, p.bncLink, 'National libraries', '123456789' },
{ 'BNE', 950, p.bneLink, 'National libraries', 'XX1234567' },
{ 'BNF', 268, p.bnfLink, 'National libraries', '123456789' },
{ 'BNMM', 3788, p.bnmmLink, 'National libraries', '000024044' },
{ 'Botanist', 428, p.botanistLink , 'Scientific databases', 'L.' },
{ 'BPN', 651, p.bpnLink , 'Biographical dictionaries', '12345678' },
{ 'CANTIC', 1273, p.canticLink, 'National libraries', 'a12345678' },
{ 'CANTICN', 9984, p.canticnLink, 'National libraries', '981058515460906706' },
{ 'CCG', 3920, p.ccgLink, 'Lighthouse identifiers', 'A1761', prefix='[[CCG (identifier)|CCG]]' },
{ 'CINII', 271, p.ciniiLink, 'Scientific databases', 'DA12345678', link = 'CiNii (identifier)' },
{ 'CWGC', 1908, p.cwgcLink, 'Other', '1234567' },
{ 'DAAO', 1707, p.daaoLink, 'Art research institutes', 'rolf-harris' },
{ 'DBLP', 2456, p.dblpLink, 'Scientific databases', '123/123' },
{ 'DIB', 6829, p.dibLink, 'Biographical dictionaries', '001953' },
{ 'DSI', 2349, p.dsiLink, 'Art research institutes', '1538' },
{ 'DTBIO', 7902, p.dtbioLink, 'Biographical dictionaries', '118554700' },
{ 'EMU', 4613, p.emuLink, 'National libraries', '15409' },
{ 'FAST', 2163, p.fastLink, 'Other', '1' },
{ 'FNZA', 6792, p.fnzaLink, 'Art research institutes', '12' },
{ 'GND', 227, p.gndLink, 'National libraries', '4079154-3' },
{ 'Google Scholar', 1960, p.googleLink, 'Scientific databases', 'QPdLuj8AAAAJ' },
{ 'HDS', 902, p.hdsLink, 'Other', '050123' },
{ 'IAAF', 1146, p.iaafLink, 'Other', '123' },
{ 'ICCU', 396, p.iccuLink, 'National libraries', 'CFIV000163' }, --formerly SBN
{ 'ICIA', 1736, p.iciaLink, 'Art research institutes', '1' },
{ 'IEU', 9070, p.ieuLink, 'Other', 'N\\A\\NationalAcademyofArtandArchitecture' },
{ 'ISNI', 213, p.isniLink, 'General', '0000-0000-6653-4145', prefix = '[[ISNI (identifier)|ISNI]]' },
{ 'J9U', 8189, p.j9uLink, 'National libraries', '987007305652505171' },
{ 'Joconde', 347, p.jocondeLink, 'Art research institutes', '12345678901' },
{ 'KULTURNAV', 1248, p.kulturnavLink, 'Art research institutes', '12345678-1234-1234-1234-1234567890AB', link = 'KulturNav (identifier)' },
{ 'LCCN', 244, p.lccnLink, 'National libraries', 'n78039510' },
{ 'LIR', 886, p.lirLink, 'Other', '1' },
{ 'LNB', 1368, p.lnbLink, 'National libraries', '123456789' },
{ 'Marina Militare', 3863, p.marinaMilitareLink, 'Lighthouse identifiers', '3856' },
{ 'MarineTraffic', 3601, p.mtLink, 'Lighthouse identifiers', '1000004707' },
{ 'MATHSN', 4955, p.mathsnLink, 'Scientific databases', '175270' },
{ 'MBA', 434, p.mbaLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz' }, --special cat name
{ 'MBAREA', 982, p.mbareaLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz area' }, --special cat name
{ 'MBI', 1330, p.mbiLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz instrument' }, --special cat name
{ 'MBL', 966, p.mblLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz label' }, --special cat name
{ 'MBP', 1004, p.mbpLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz place' }, --special cat name
{ 'MBRG', 436, p.mbrgLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz release group' }, --special cat name
{ 'MBS', 1407, p.mbsLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz series' }, --special cat name
{ 'MBW', 435, p.mbwLink, 'Other', '12345678-1234-1234-1234-1234567890AB', category = 'MusicBrainz work' }, --special cat name
{ 'MGP', 549, p.mgpLink, 'Scientific databases', '123456' },
{ 'NARA', 1225, p.naraLink, 'Other', '12345678' },
{ 'NCL', 1048, p.nclLink, 'National libraries', '1081436' },
{ 'NDL', 349, p.ndlLink, 'National libraries', '012345678' },
{ 'NGA', 3563, p.ngaLink, 'Lighthouse identifiers', '114-5592'},
{ 'NGV', 2041, p.ngvLink, 'Art galleries and museums', '12354' },
{ 'NKC', 691, p.nkcLink, 'National libraries', 'abcd12345678901234' },
{ 'NLA', 409, p.nlaLink, 'National libraries', '123456789012' },
{ 'NLG', 3348, p.nlgLink, 'National libraries', '12345678' },
{ 'NLK', 5034, p.nlkLink, 'National libraries', 'KAB197000000' },
{ 'NLP', 1695, p.nlpLink, 'National libraries', '9810123456789012345' },
{ 'NLR', 1003, p.nlrLink, 'National libraries', '123456789' },
{ 'NSK', 1375, p.nskLink, 'National libraries', '123456789' },
{ 'NTA', 1006, p.ntaLink, 'National libraries', '12345678X' },
{ 'ORCID', 496, p.orcidLink, 'General', '0000-0002-7398-5483', prefix = '[[ORCID (identifier)|ORCID]]' },
{ 'PIC', 2750, p.picLink, 'Art research institutes', '1' },
{ 'PLWABN', 7293, p.plwabnLink, 'National libraries', '9812345678905606' },
{ 'Publons', 3829, p.publonsLink, 'Scientific databases', '2776255' },
{ 'RID', 1053, p.ridLink, 'Scientific databases', 'A-1234-1934' },
{ 'RISM', 5504, p.rismLink, 'Other', 'pe1', prefix = '[[RISM (identifier)|RISM (France)]]' },
{ 'RERO', 3065, p.reroLink, 'Other', '02-A012345678', prefix = '[[RERO (identifier)|RERO (Switzerland)]]' },
{ 'RKDartists', 650, p.rkdartistsLink, 'Art research institutes', '123456' },
{ 'RKDID', 350, p.rkdidLink, 'Art research institutes', '123456' },
{ 'RSL', 947, p.rslLink, 'National libraries', '123456789' },
{ 'Scopus', 1153, p.scopusLink, 'Scientific databases', '7005487412' },
{ 'SELIBR', 906, p.selibrLink, 'National libraries', '123456' },
{ 'SIKART', 781, p.sikartLink, 'Art research institutes', '123456789' },
{ 'SNAC-ID', 3430, p.snacLink, 'Other', 'A' },
{ 'SUDOC', 269, p.sudocLink, 'Other', '026927608', prefix = '[[SUDOC (identifier)|SUDOC (France)]]' },
{ 'TA98', 1323, p.ta98Link, 'Scientific databases', 'A12.3.45.678' },
{ 'TDVİA', 7314, p.tdviaLink, 'Other', 'asim-b-behdele' },
{ 'TePapa', 3544, p.tepapaLink, 'Art galleries and museums', '1' },
{ 'TLS', 1362, p.tlsLink, 'Other', 'Abcd' },
{ 'Trove', 1315, p.troveLink, 'Other', '12345678', prefix = '[[Trove (identifier)|Trove (Australia)]]' }, --formerly NLA-person
{ 'UKPARL', 6213, p.ukparlLink, 'Other', 'AQUupyiR' },
{ 'ULAN', 245, p.ulanLink, 'Art research institutes', '500123456' },
{ 'USCG', 3723, p.uscgLink, 'Lighthouse identifiers', '6-0695'},
{ 'USCongress', 1157, p.uscongressLink, 'Other', 'A000123', link = 'US Congress (identifier)' },
{ 'VcBA', 8034, p.vcbaLink, 'National libraries', '494/9793' },
{ 'VIAF', 214, p.viafLink, 'General', '123456789', prefix = '[[VIAF (identifier)|VIAF]]' },
{ 'WORLDCATID', 7859, p.worldcatidLink, 'General', 'lccn-n78-95332', link = 'WorldCat Identities (identifier)' },
{ 'ZBMATH', 1556, p.zbmathLink, 'Scientific databases', 'turing.alan-m' },
}
-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
{ 'DNB', 'GND' }, --Deutsche Nationalbibliothek -> Gemeinsame Normdatei
{ 'MusicBrainz', 'MBA' },
{ 'MusicBrainz artist', 'MBA' },
{ 'MusicBrainz label', 'MBL' },
{ 'MusicBrainz release group', 'MBRG' },
{ 'MusicBrainz work', 'MBW' },
{ 'SBN', 'ICCU' }, --SBN alias to be deprecated at a later stage
{ 'TDVIA', 'TDVİA' }, --alias name without diacritics
{ 'tdvia', 'TDVİA' }, --lowercase variant without diacritics
}
-- Deprecated aliases to p.conf; tracked in [[Category:Articles with deprecated authority control identifiers]]
-- Format: { 'deprecated parameter name', 'replacement parameter name in p.conf' }
p.deprecated = {
{ 'GKD', 'GND' },
{ 'PND', 'GND' },
{ 'RLS', 'RSL' },
{ 'SWD', 'GND' },
{ 'NARA-organization', 'NARA' },
{ 'NARA-person', 'NARA' },
}
--[[==========================================================================]]
--[[ Main ]]
--[[==========================================================================]]
function p.authorityControl( frame )
local resolveEntity = require( 'Module:ResolveEntityId' )
local parentArgs = frame:getParent().args --WD IDs added here later
local iParentArgs = 0 --count original/manual parent args only later
local worldcatCat = ''
local elementsCat = ''
local multipleIdCat = ''
local suppressedIdCat = ''
local suppressedIdCatArts = ''
local deprecatedIdCat = ''
local differentOnWDCat = ''
local sameOnWDCat = ''
local stateCat = ''
--redirect aliases to proper parameter names
for _, a in pairs( p.aliases ) do
local alias, param = a[1], a[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
parentArgs[param] = parentArgs[alias]
end
end
--redirect deprecated parameters to proper parameter names, and assign tracking cat
for _, d in pairs( p.deprecated ) do
local dep, param = d[1], d[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
parentArgs[param] = parentArgs[dep]
if namespace == 0 then
deprecatedIdCat = '[[Category:Articles with deprecated authority control identifiers|'..dep..']]'
end
end
end
--use QID= parameter for testing/example purposes only
local itemId = nil
if namespace ~= 0 then
local qid = parentArgs['qid'] or parentArgs['QID']
if qid then
itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
itemId = resolveEntity._id(itemId) --nil if unresolvable
end
elseif mw.wikibase then
itemId = mw.wikibase.getEntityIdForCurrentPage()
end
--Wikidata fallback if available
if itemId then
local suppressedIdCount = 0
local iMatches = 0
for _, params in ipairs( p.conf ) do
if params[2] > 0 then
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val == nil or val == '' then
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
if wikidataIds[1] then
if val == '' and (namespace == 0 or testcases) then
suppressedIdCount = suppressedIdCount + 1
suppressedIdCat = '[[Category:Articles with suppressed authority control identifiers|'..params[1]..']]'
else
parentArgs[params[1]] = wikidataIds[1] --add ID from WD
end
end
else
iParentArgs = iParentArgs + 1
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
if wikidataIds[1] and differentOnWDCat == '' then
local bMatch = false
for _, wd in pairs( wikidataIds ) do
if val == wd then
iMatches = iMatches + 1
bMatch = true
end
end
if bMatch == false then
differentOnWDCat = '[[Category:Pages using authority control with parameters different on Wikidata|'..params[1]..']]'
end end end end end
if iMatches > 0 and iMatches == iParentArgs then
sameOnWDCat = '[[Category:Pages using authority control with parameters all matching Wikidata]]'
end
if parentArgs['arts'] == 'arts' and suppressedIdCount > 0 then
if namespace == 0 or testcases then
local s = 's'
if suppressedIdCount == 1 then s = '' end
local sCat = 'ACArt with '..suppressedIdCount..' suppressed element'..s
suppressedIdCatArts = addCat(sCat)
end
end
end
--configure rows
local rct = 0
local sectionOrder = {
'General',
'National libraries',
'Art galleries and museums',
'Art research institutes',
'Biographical dictionaries',
'Scientific databases',
'Lighthouse identifiers',
'Other'
}
local sections = {
['General'] = {},
['National libraries'] = {},
['Art galleries and museums'] = {},
['Art research institutes'] = {},
['Biographical dictionaries'] = {},
['Scientific databases'] = {},
['Lighthouse identifiers'] = {},
['Other'] = {}
}
--don't show CANTIC if CANTICN is present, since they both go to the Library of Catalonia
--and the library has deprecated CANTIC IDs in favor of CANTICN IDs
if parentArgs.CANTICN or parentArgs.canticn then
parentArgs.CANTIC = ''
parentArgs.cantic = ''
end
--don't show NLP if PLWABN is present, since they both go to the National Library of Poland
--and the library has deprecated NLP IDs in favor of PLWABN IDs
if parentArgs.PLWABN or parentArgs.plwabn then
parentArgs.NLP = ''
parentArgs.nlp = ''
end
for _, params in ipairs( p.conf ) do
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
local tval, tlinks = {}, {} --init tables
if val and val ~= '' and type(params[3]) == 'function' then
table.insert( tval, val )
if params.prefix then
table.insert( tlinks, params[3]( val, '1' ) )
else
table.insert( tlinks, params[3]( val ) )
end
end
--collect other unique vals (IDs) from WD, if present
if itemId and tval[1] then
local nextIdVal = 2
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
for _, v in pairs( wikidataIds ) do
local bnew = true
for _, w in pairs( tval ) do
if v == w then bnew = false end
end
if bnew then
table.insert( tval, v )
table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )
nextIdVal = nextIdVal + 1
end
end
end
--assemble
if tval[1] then
table.insert( sections[params[4]], p.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )
rct = rct + 1
if tval[2] then
multipleIdCat = p.getCatForId( 'multiple' )
end
end
end
--WorldCat-VIAF & WorldCat-LCCN
local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
if worldcatId == nil then --if WORLDCATID absent but unsuppressed
local viafId = parentArgs['viaf'] or parentArgs['VIAF']
local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
table.insert( sections['General'], p.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' WorldCat (via VIAF)]', nil, false ) )
if namespace == 0 then
worldcatCat = '[[Category:Articles with WorldCat-VIAF identifiers]]'
end
rct = rct + 1
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
local lccnParts = p.splitLccn( lccnId )
if lccnParts and lccnParts[1] ~= 'sh' then
local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
table.insert( sections['General'], p.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' WorldCat (via Library of Congress)]', nil, false ) )
if namespace == 0 then
worldcatCat = '[[Category:Articles with WorldCat-LCCN identifiers]]'
end
end
rct = rct + 1
end
end
--configure Navbox
local outString = ''
local extrap = true
local extra = parentArgs.extralist
if extra == nil or extra == '' then
extrap = false
end
if rct > 0 or extrap then
local Navbox = require('Module:Navbox')
local sectionID = 1
local args = { pid = 'identifiers' } -- #target the list of identifiers
if testcases and itemId then args.qid = itemId end --expensive
local pencil = require('Module:EditAtWikidata')._showMessage(args)
local navboxArgs = {
name = 'Authority control',
navboxclass = 'authority-control',
bodyclass = 'hlist',
state = parentArgs.state or 'autocollapse',
navbar = 'off'
}
for _, sectName in ipairs(sectionOrder) do
if #sections[sectName] ~= 0 then
navboxArgs['group'..sectionID] = sectName
navboxArgs['list'..sectionID] = table.concat(sections[sectName])
sectionID = sectionID + 1
end
end
if extrap then
if parentArgs.extragroup then
navboxArgs['group'..sectionID] = parentArgs.extragroup
else
navboxArgs['group'..sectionID] = 'Additional'
end
navboxArgs['list'..sectionID] = extra
sectionID = sectionID + 1
end
if navboxArgs.list2 then
navboxArgs.title = '[[Help:Authority control|Authority control]]'..pencil
else
local sect = navboxArgs.group1
if sect == 'General' or sect == 'Other' or sect == 'Additional' then
-- Just say "Authority control" with no label if only general or only other IDs are present
-- since "general" is redundant and "other" is silly when there's nothing to contrast it with
navboxArgs.group1 = '[[Help:Authority control|Authority control]]'..pencil
else
navboxArgs.group1 = '[[Help:Authority control|Authority control: '..sect..']] '..pencil
end
end
outString = Navbox._navbox(navboxArgs)
end
--auxCats
if rct == 0 or rct >= 25 then
if namespace == 0 or testcases then
local eCat = 'AC with '..rct..' elements'
elementsCat = addCat(eCat)
end
end
if parentArgs.state then
if namespace == 0 or testcases then
local sCat
if parentArgs.state == 'collapsed' then sCat = 'AC using state parameter: collapsed'
elseif parentArgs.state == 'expanded' then sCat = 'AC using state parameter: expanded'
elseif parentArgs.state == 'autocollapse' then sCat = 'AC using state parameter: autocollapse'
else sCat = 'AC using state parameter: other'
end
stateCat = addCat(sCat)
end
end
local auxCats = worldcatCat..elementsCat..multipleIdCat..suppressedIdCat..suppressedIdCatArts..
deprecatedIdCat..differentOnWDCat..sameOnWDCat..stateCat
if testcases then
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
end
--out
outString = outString..auxCats
if namespace ~= 0 then
outString = mw.ustring.gsub(outString, '(%[%[)(Category:Articles)', '%1:%2') --by definition
end
return outString
end
return p
cd0db2cc5bc4d9d60808eaacdd367d8aacb169ea
Module:ResolveEntityId
828
92
200
199
2022-09-04T15:24:53Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local p = {}
function p._id(idOrTitle, alt)
local function checkId(id)
if id and mw.wikibase.entityExists(id) then
local sitelink = mw.wikibase.getSitelink(id)
if sitelink then
return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(id).id
end
return mw.wikibase.getEntity(id).id
else
return alt
end
end
if type(idOrTitle) == 'string' then
idOrTitle = mw.ustring.upper(mw.ustring.sub(idOrTitle, 1, 1)) .. mw.ustring.sub(idOrTitle, 2)
if mw.wikibase.isValidEntityId(idOrTitle) then
-- idOrTitle is in the proper format for a Wikidata entity ID
return checkId(idOrTitle)
else
local eid = mw.wikibase.getEntityIdForTitle(idOrTitle)
if eid then
-- idOrTitle is a title that matches a Wikidata entity
local instanceOf = mw.wikibase.getBestStatements(eid, 'P31')[1] --instance of
if not instanceOf or instanceOf.mainsnak.datavalue.value.id ~= 'Q4167410' then
-- instance-of value is missing or is not "disambiguation"
return checkId(eid)
end
else
-- idOrTitle is a title, but no wikidata item exists for that title
local rtarget = mw.title.new(idOrTitle).redirectTarget
if rtarget then
-- title is a Wikipedia redirect
return p._id(rtarget.fullText, alt)
end
end
end
end
return alt
end
function p.entityid(frame)
return p._id(frame.args[1], frame.args[2])
end
return p
520d9c0247df2692f8909c86f05c6eb7aab182c0
Template:If empty
10
93
202
201
2022-09-04T15:24:54Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:If empty|main}}<noinclude>{{Documentation}}</noinclude>
745940b7bdde8a1585c887ee4ee5ce81d98461a4
Module:If empty
828
94
204
203
2022-09-04T15:24:54Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local p = {}
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:If empty', removeBlanks = false})
local lastk = 0
for k,v in ipairs(args) do
if v ~= '' then
return v
end
lastk = k
end
end
return p
4bfc0c7c8bf3b63144db1ea12f2260db00421233
Template:Convert
10
95
206
205
2022-09-04T15:24:54Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{{{{♥|safesubst:}}}#invoke:convert|convert}}</includeonly><noinclude>
{{documentation}}
<!-- Add categories to the /doc subpage, interwikis to Wikidata, not here -->
</noinclude>
952ac4080dc4a427c4a65db9951c8a4f4c91c626
Template:Cite book
10
96
208
207
2022-09-04T15:24:55Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=book
}}</includeonly><noinclude>
{{documentation}}
{{collapse top|TemplateData}}
{{Cite book/TemplateData}}
{{collapse bottom}}
</noinclude>
c474cbe5d051e08f516083d594207d449245c717
Template:Cite encyclopedia
10
97
210
209
2022-09-04T15:24:55Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=encyclopaedia
}}</includeonly><noinclude>
{{documentation}}
[[Category:Lua-based templates]]
</noinclude>
a5fbaa0493d06b11ef4dd711383f9fd5174a4238
Template:Navbox
10
98
212
211
2022-09-04T15:24:55Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
fe9b964401f895918ee4fe078678f1722a3c41ec
Template:Other uses
10
99
214
213
2022-09-04T15:24:55Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:other uses|otheruses}}<noinclude>{{documentation}}</noinclude>
3bd6c67c92b11a14d2e58145b096152fbc066580
Template:Sfn
10
100
216
215
2022-09-04T15:24:56Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:Footnotes|sfn|template=sfn}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using sfn with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Sfn]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | 3 | 4 | 5 | ignore-err | loc | p | page | pages | postscript | pp | ps | ref | Ref }}<noinclude>
{{documentation}}
</noinclude>
eab6519b2a87e18dc40f39343c71f5848977cc93
Template:SfnRef
10
101
218
217
2022-09-04T15:24:56Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{safesubst<noinclude />:#invoke:Footnotes|sfnref}}<noinclude>
{{documentation}}
</noinclude>
56e03dd26fcd9edbe71a96b5c5c84198863b964b
Module:Footnotes
828
102
220
219
2022-09-04T15:24:56Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;
--[[--------------------------< A R G S _ D E F A U L T >------------------------------------------------------
a table to specify initial values.
]]
local args_default = {
bracket_left = '',
bracket_right = '',
bracket_year_left = '',
bracket_year_right = '',
postscript = '',
page = '',
pages = '',
location = '',
page_sep = ", p. ",
pages_sep = ", pp. ",
ref = '',
template = 'harv', -- if template name not provided in {{#invoke:}} use this
};
--[[--------------------------< T A R G E T _ C H E C K >------------------------------------------------------
look for anchor_id (CITEREF name-list and year or text from |ref=) in anchor_id_list
the 'no target' error may be suppressed with |ignore-err=yes when target cannot be found because target is inside
a template that wraps another template; 'multiple targets' error may not be suppressed
]]
local function target_check (anchor_id, args)
local namespace = mw.title.getCurrentTitle().namespace;
local anchor_id_list_module = mw.loadData ('Module:Footnotes/anchor_id_list');
local anchor_id_list = anchor_id_list_module.anchor_id_list;
local article_whitelist = anchor_id_list_module.article_whitelist;
local template_list = anchor_id_list_module.template_list;
local whitelist_module = mw.loadData ('Module:Footnotes/whitelist');
local whitelist = whitelist_module.whitelist;
local special_patterns = whitelist_module.special_patterns;
local DNB_special_patterns = whitelist_module.DNB_special_patterns;
local DNB_template_names = whitelist_module.DNB_template_names;
if 10 == namespace then
return ''; -- automatic form of |no-tracking=yes; TODO: is this too broad?
end
local tally = anchor_id_list[anchor_id]; -- nil when anchor_id not in list; else a tally
local msg;
local category;
if not tally then
if args.ignore then
return ''; -- if ignore is true then no message, no category
end
if article_whitelist and article_whitelist[anchor_id] then -- if an article-local whitelist and anchor ID is in it
return ''; -- done
end
local wl_anchor_id = anchor_id; -- copy to be modified to index into the whitelist
if args.year then -- for anchor IDs created by this template (not in |ref=) that have a date
if args.year:match ('%d%l$') or -- use the date value to determine if we should remove the disambiguator
args.year:match ('n%.d%.%l$') or
args.year:match ('nd%l$') then
wl_anchor_id = wl_anchor_id:gsub ('%l$', ''); -- remove the disambiguator
end
end
local t_tbl = whitelist[wl_anchor_id]; -- get list of templates associated with this anchor ID
if t_tbl then -- when anchor ID not whitelisted t_tbl is nil
for _, t in ipairs (t_tbl) do -- spin through the list of templates associated with this anchor ID
if template_list[t] then -- if associated template is found in the list of templates in the article
return ''; -- anchor ID is whitlisted and article has matching template so no error
end
end
end
for _, pattern in ipairs (special_patterns) do -- spin through the spcial patterns and try to match
if anchor_id:match (pattern) then
return '';
end
end
for _, dnb_t in ipairs (DNB_template_names or {}) do -- getting desparate now, are there any DNB templates? DNB_template_names may be nil; empty table prevents script error
if template_list[dnb_t] then -- if the article has this DNB template
for _, pattern in ipairs (DNB_special_patterns) do -- spin through the DNB-specifiec wildcard patterns
if anchor_id:match (pattern) then -- and attempt a match
return ''; -- found a match
end
end
end
end
msg = 'no target: ' .. anchor_id; -- anchor_id not found
category = '[[Category:Harv and Sfn no-target errors]]';
elseif 1 < tally then
msg = 'multiple targets (' .. tally .. '×): ' .. anchor_id; -- more than one anchor_id in this article
category = 0 == namespace and '[[Category:Harv and Sfn multiple-target errors]]' or ''; -- only categorize in article space
return '<span class="error harv-error" style="display: inline; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category;
end
-- category = 0 == namespace and '[[Category:Harv and Sfn template errors]]' or ''; -- only categorize in article space
category = 0 == namespace and category or ''; -- only categorize in article space
--use this version to show error messages
-- return msg and '<span class="error harv-error" style="display: inline; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category or '';
--use this version to hide error messages
return msg and '<span class="error harv-error" style="display: none; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category or '';
end
--[[--------------------------< I S _ Y E A R >----------------------------------------------------------------
evaluates param to see if it is one of these forms with or without lowercase letter disambiguator:
YYYY
n.d.
nd
c. YYYY
YYYY–YYYY (separator is endash)
YYYY–YY (separator is endash)
return true when param has a recognized form; false else
]]
local patterns_date= {
'^%d%d%d%d?%l?$',
'^n%.d%.%l?$',
'^nd%l?$',
'^c%. %d%d%d%d?%l?$',
'^%d%d%d%d–%d%d%d%d%l?$',
'^%d%d%d%d–%d%d%l?$',
}
local function is_year (param, args)
args.year = ''; -- used for harv error;
for _, pattern in ipairs (patterns_date) do
if mw.ustring.match (param, pattern) then
args.year = param; -- used for harv error;
return true;
end
end
end
--[[--------------------------< C O R E >----------------------------------------------------------------------
returns an anchor link (CITEREF) formed from one to four author names, year, and insource location (|p=, |pp=, loc=)
]]
local function core( args )
local result;
local err_msg = ''
if args.P5 ~= '' then
if is_year (args.P5, args) then
result = table.concat ({args.P1, ' et al. ', args.bracket_year_left, args.P5, args.bracket_year_right});
else
args.P5 = ''; -- when P5 not a year don't include in anchor
result = table.concat ({args.P1, ' et al.'}); -- and don't render it
end
elseif args.P4 ~= '' then
if is_year (args.P4, args) then
result = table.concat ({args.P1, ', ', args.P2, ' & ', args.P3, ' ', args.bracket_year_left, args.P4, args.bracket_year_right}); -- three names and a year
else
result = table.concat ({args.P1, ' et al.'}); -- four names
end
elseif args.P3 ~= '' then
if is_year (args.P3, args) then
result = table.concat ({args.P1, ' & ', args.P2, ' ', args.bracket_year_left, args.P3, args.bracket_year_right}); -- two names and a year
else
result = table.concat ({args.P1, ', ', args.P2, ' ', ' & ', args.P3}); -- three names
end
elseif args.P2 ~= '' then
if is_year (args.P2, args) then
result = table.concat ({args.P1, ' ', args.bracket_year_left, args.P2, args.bracket_year_right}); -- one name and year
else
result = table.concat ({args.P1, ' & ', args.P2}); -- two names
end
else
result = args.P1; -- one name
end
-- when author-date result ends with a dot (typically when the last positional parameter holds 'n.d.')
-- and when no in-source location (no |p=, |pp=, or |loc=)
-- and when the first or only character in args.postscript is a dot
-- remove the author-date result trailing dot
-- the author-date result trailing dot will be replaced later with the content of args.postscript (usually a dot)
if ('.' == result:sub(-1)) and ('.' == args.postscript:sub(1)) and ('' == args.page) and ('' == args.pages) and ('' == args.location) then
result = result:gsub ('%.$', '');
end
if args.ref ~= 'none' then
local anchor_id;
if args.ref ~= '' then
anchor_id = mw.uri.anchorEncode (args.ref);
err_msg = target_check (anchor_id, args);
result = table.concat ({'[[#', anchor_id, '|', result, ']]'});
else
anchor_id = mw.uri.anchorEncode (table.concat ({'CITEREF', args.P1, args.P2, args.P3, args.P4, args.P5}));
err_msg = target_check (anchor_id, args);
result = table.concat ({'[[#', anchor_id, '|', result, ']]'});
end
end
if args.page ~= '' then
result = table.concat ({result, args.page_sep, args.page});
elseif args.pages ~= ''then
result = table.concat ({result, args.pages_sep, args.pages});
end
if args.location ~= '' then
result = table.concat ({result, ', ', args.location});
end
result = table.concat ({args.bracket_left, result, args.bracket_right, args.postscript}):gsub ('%s+', ' '); -- strip redundant spaces
return result .. err_msg;
end
--[[--------------------------< H Y P H E N _ T O _ D A S H >--------------------------------------------------
Converts a hyphen to a dash under certain conditions. The hyphen must separate
like items; unlike items are returned unmodified. These forms are modified:
letter - letter (A - B)
digit - digit (4-5)
digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
letterdigit - letterdigit (A1-A5) (an optional separator between letter and
digit is supported – a.1-a.5 or a-1-a-5)
digitletter - digitletter (5a - 5d) (an optional separator between letter and
digit is supported – 5.a-5.d or 5-a-5-d)
any other forms are returned unmodified.
str may be a comma- or semicolon-separated list
This code copied from Module:Citation/CS1. The only modification is to require Module:Citation/CS1/Utilities
so that it has access to the functions is_set() and has_accept_as_written()
]]
local function hyphen_to_dash( str )
local utilities = require ('Module:Citation/CS1/Utilities'); -- only modification so that this function has access to is_set() and has_accept_as_written()
if not utilities.is_set (str) then
return str;
end
local accept; -- Boolean
str = str:gsub ('&[nm]dash;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace HTML numeric entity with hyphen character
str = str:gsub (' ', ' '); -- replace entity with generic keyboard space character
local out = {};
local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any
for _, item in ipairs (list) do -- for each item in the list
item, accept = utilities.has_accept_as_written (item); -- remove accept-this-as-written markup when it wraps all of item
if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators
if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit)
item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter)
item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit
item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit
item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter
item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters
else
item = mw.ustring.gsub (item, '%s*[–—]%s*', '–'); -- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace
end
end
table.insert (out, item); -- add the (possibly modified) item to the output table
end
local temp_str = ''; -- concatenate the output table into a comma separated string
temp_str, accept = utilities.has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out
if accept then
temp_str = utilities.has_accept_as_written (str); -- when global markup removed, return original str; do it this way to suppress boolean second return value
return temp_str;
else
return temp_str; -- else, return assembled temp_str
end
end
--[[--------------------------< A R G S _ F E T C H >---------------------------------------------------------
Because all of the templates share a common set of parameters, a single common function to fetch those parameters
from frame and parent frame.
]]
local function args_fetch (frame, ps)
local args = args_default; -- create a copy of the default table
local pframe = frame:getParent(); -- point to the template's parameter table
for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any
args[k] = v;
end
args.postscript = pframe.args.postscript or pframe.args.ps or ps;
if 'none' == args.postscript then
args.postscript = '';
end
args.page = pframe.args.p or pframe.args.page or '';
args.pages = pframe.args.pp or pframe.args.pages or '';
args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
args.location = pframe.args.loc or '';
args.ref = pframe.args.ref or pframe.args.Ref or '';
args.ignore = ('yes' == pframe.args['ignore-false-positive']) or ('yes' == pframe.args['ignore-err']);
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- loop through the five positional parameters and trim if set else empty string
args[v] = (pframe.args[i] and mw.text.trim (pframe.args[i])) or '';
end
if args.P5 and not is_year (args.P5, args) then
local i = 6; -- initialize the indexer to the sixth positional parameter
while pframe.args[i] do -- in case there are too many authors loop through the authors looking for a year
local v = mw.text.trim (pframe.args[i]); -- trim
if is_year (v, args) then -- if a year
args.P5 = v; -- overwrite whatever was in args.P5 with year
break; -- and abandon the search
end
i = i + 1; -- bump the indexer
end
end
return args;
end
--[[--------------------------< H A R V A R D _ C I T A T I O N >----------------------------------------------
common entry point for:
{{harvard citation}} aka {{harv}}
{{Harvard citation no brackets}} aka {{harvnb}}
{{harvcol}}
{{harvcolnb}}
{{harvcoltxt}}
{{Harvard citation text}} aka {{harvtxt}}
{{Harvp}}
Distinguishing features (brackets and page separators) are specified in this module's {{#invoke}} in the respective templates.
]]
local function harvard_citation (frame)
local args = args_fetch (frame, ''); -- get the template and invoke parameters; default postscript is empty string
return core (args);
end
--[[--------------------------< S T R I P _ U R L >------------------------------------------------------------
used by sfn() and sfnm(). This function fixes an issue with reference tooltip gadget where the tooltip is not displayed
when an insource locator (|p=, |pp=, |loc=) has an external wikilink that contains a # character
strip uri-reserved characters from urls in |p=, |pp-, and |loc= parameters The researved characters are:
!#$&'()*+,/:;=?@[]
]]
local function strip_url (pages)
local escaped_uri;
if not pages or ('' == pages) then
return pages;
end
for uri in pages:gmatch ('%[(%a[%w%+%.%-]*://%S+)') do -- for each external link get the uri
escaped_uri = uri:gsub ("([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); -- save a copy with lua pattern characters escaped
uri = uri:gsub ("[!#%$&'%(%)%*%+,/:;=%?@%[%]%.%%]", ''); -- remove reserved characters and '%' because '%20' (space character) is a lua 'invalid capture index'
pages = pages:gsub (escaped_uri, uri, 1); -- replace original uri with the stripped version
end
return pages;
end
--[[--------------------------< S F N >------------------------------------------------------------------------
entry point for {{sfn}} and {{sfnp}}
]]
local function sfn (frame)
local args = args_fetch (frame, '.'); -- get the template and invoke parameters; default postscript is a dot
local result = core (args); -- go make a CITEREF anchor
-- put it all together and then strip redundant spaces
local name = table.concat ({'FOOTNOTE', args.P1, args.P2, args.P3, args.P4, args.P5, strip_url (args.page), strip_url (args.pages), strip_url (args.location)}):gsub ('%s+', ' ');
return frame:extensionTag ({name='ref', args={name=name}, content=result});
end
--[[--------------------------< S F N M >----------------------------------------------------------------------
common entry point for {{sfnm}} and {{sfnmp}}
Distinguishing features (brackets) are specified in this module's {{#invoke}} in the respective templates.
]]
local function sfnm (frame)
local args = args_default; -- create a copy of the default table
local pframe = frame:getParent(); -- point to the template's parameter table
local n = 1; -- index of source; this is the 'n' in na1, ny, etc
local first_pnum = 1; -- first of a pair of positional parameters
local second_pnum = 2; -- second of a pair of positional parameters
local last_ps = 0; -- index of the last source with |nps= set
local last_index = 0; -- index of the last source; these used to determine which of |ps= or |nps= will terminate the whole rendering
local out = {}; -- table to hold rendered sources
local footnote = {'FOOTNOTE'}; -- all author, date, insource location stuff becomes part of the reference's footnote id; added as we go
for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any
args[k] = v;
end
while true do
if not pframe.args[table.concat ({n, 'a1'})] and not pframe.args[first_pnum] then
break; -- no na1 or matching positional parameter so done
end
if pframe.args[table.concat ({n, 'a1'})] then -- does this source use named parameters?
for _, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- initialize for this source
args[v] = '';
end
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- extract author and year parameters for this source
args[v] = pframe.args[table.concat ({n, 'a', i})] or ''; -- attempt to assign author name
if '' == args[v] then -- when there wasn't an author name
args[v] = pframe.args[table.concat ({n, 'y'})] or ''; -- attempt to assign year
break; -- done with author/date for this source
end
end
else -- this source uses positional parameters
args.P1 = mw.text.trim (pframe.args[first_pnum]); -- yes, only one author supported
args.P2 = (pframe.args[second_pnum] and mw.text.trim (pframe.args[second_pnum])) or ''; -- when positional author, year must also be positional
for _, v in ipairs ({'P3', 'P4', 'P5'}) do -- blank the rest of these for this source
args[v] = '';
end
first_pnum = first_pnum + 2; -- source must use positional author and positional year
second_pnum = first_pnum + 1; -- bump these for possible next positional source
end
args.postscript = pframe.args[table.concat ({n, 'ps'})] or '';
if 'none' == args.postscript then -- this for compatibility with other footnote templates; does nothing
args.postscript = '';
end
args.ref = pframe.args[table.concat ({n, 'ref'})] or ''; -- alternate reference for this source
args.page = pframe.args[table.concat ({n, 'p'})] or ''; -- insource locations for this source
args.pages = pframe.args[table.concat ({n, 'pp'})] or '';
args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
args.location = pframe.args[table.concat ({n, 'loc'})] or '';
args.ignore = ('yes' == pframe.args[table.concat ({n, 'ignore-false-positive'})]) or ('yes' == pframe.args[table.concat ({n, 'ignore-err'})]);
table.insert (out, core (args)); -- save the rendering of this source
for k, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- create the FOOTNOTE id
if '' ~= args[v] then
table.insert (footnote, args[v]);
end
end
for k, v in ipairs ({'page', 'pages', 'location'}) do -- these done separately so that we can strip uri-reserved characters from extlinked page numbers
if '' ~= args[v] then
table.insert (footnote, strip_url (args[v]))
end
end
last_index = n; -- flags used to select terminal postscript from nps or from end_ps
if '' ~= args.postscript then
last_ps = n;
end
n = n+1; -- bump for the next one
end
local name = table.concat (footnote):gsub ('%s+', ' '); -- put the footnote together and strip redundant space
args.end_ps = pframe.args.postscript or pframe.args.ps or '.'; -- this is the postscript for the whole not for the individual sources
if 'none' == args.end_ps then -- not an original sfnm parameter value; added for compatibility with other footnote templates
args.end_ps = '';
end
local result = table.concat ({table.concat (out, '; '), (last_index == last_ps) and '' or args.end_ps});
return frame:extensionTag ({name='ref', args={name=name}, content=result});
end
--[[--------------------------< S F N R E F >------------------------------------------------------------------
implements {{sfnref}}
]]
local function sfnref (frame)
local args = getArgs (frame);
local out = {};
for i=1, 5 do -- get the first five args if there are five args
if args[i] then
out[i] = args[i];
else
break; -- less than 5 args break out
end
end
if 5 == #out then -- when we have seen five args there may bemore
local i = 6; -- initialize the indexer to the sixth positional parameter
while args[i] do -- in case there are too many authors loop through the authors looking for a year
if is_year (args[i], args) then -- if a year
out[5] = args[i]; -- overwrite whatever was in args[5] with year
break; -- and abandon the search
end
i = i + 1; -- bump the indexer
end
end
return mw.uri.anchorEncode ('CITEREF' .. table.concat (out));
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
harvard_citation = harvard_citation,
sfn = sfn,
sfnm = sfnm,
sfnref = sfnref,
};
1900e2ea7aff0f4023cd9a8f39ece502cc07e045
Module:Footnotes/anchor id list
828
103
222
221
2022-09-04T15:24:57Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require('Module:No globals');
local data = mw.loadData ('Module:Footnotes/anchor id list/data');
local whitelist = mw.loadData ('Module:Footnotes/whitelist');
local Lang_obj = mw.language.getContentLanguage(); -- used by template_list_add() to uppercase first letter of template name TODO: better way to do that?
local redirects_date = {
['date'] = true,
['datetomos'] = true,
['formatdate'] = true,
['isotodmymdy'] = true,
['isotomos'] = true,
}
local redirects_patent = { -- special case cs1-like templates because uses different parameters for name and date in anchor ID
['Cite patent'] = true,
['Citeref patent'] = true,
['Ref patent'] = true,
}
local redirects_sfnref = {
['sfnref'] = true,
['harvid'] = true,
}
local aliases_author = { -- these use pseudo-patterns in the same way as cs1|2; '#' represents 1 or more enumerator digits
'last#',
'author#',
'surname#',
'author-last#',
'author#-last',
'subject#',
'host#',
}
local aliases_contributor = {
'contributor#',
'contributor-last#',
'contributor#-last',
'contributor-surname#',
'contributor#-surname',
}
local aliases_editor = {
'editor#',
'editor-last#',
'editor#-last',
'editor-surname#',
'editor#-surname',
}
local aliases_harvc_author = {
'last#',
'author#',
}
local aliases_inventor = { -- cite patent
'inventor#',
'inventor-last#',
'inventor#-last',
'inventor-surname#',
'inventor#-surname',
'invent#',
'invent-#',
}
local alias_patterns_date = { -- normal lua patterns for most cs1|2-like templates
'|%s*year%s*=%s*',
'|%s*date%s*=%s*',
'|%s*publication%-?date%s*=%s*',
'|%s*air%-?date%s*=%s*',
}
local alias_patterns_harvc_date = { -- normal lua patterns for harvc template
'|%s*anchor%-year%s*=%s*',
'|%s*year%s*=%s*',
}
local alias_patterns_patent_date = { -- normal lua patterns for cite patent templates
'|%s*issue%-date%s*=%s*',
'|%s*gdate%s*=%s*',
'|%s*publication%-date%s*=%s*',
'|%s*pubdate%s*=%s*',
}
local patterns_date = { -- normal lua patterns
'(%d%d%d%d–%d%d%d%d%l?)$', -- YYYY–YYYY four-digit year range at end (Season YYYY–YYYY); with or without dab
'^(%d%d%d%d–%d%d%l?)$', -- YYYY–YY two-digit year range; with or without dab
'^(c%. %d%d%d%d?%l?)$', -- three- or four-digit circa year; with or without dab
'(%d%d%d%d?%l?)$', -- three- or four-digit year at end of date (dmy or mdy); with or without dab
'^(%d%d%d%d?%l?)', -- three- or four-digit year at beginning of date (ymd or YYYY); with or without dab
'^(n%.d%.%l?)$', -- 'no date' with dots; with or without dab
'^(nd%l?)$', -- 'no date' without dots; with or without dab
}
local patterns_tags = {
'<nowiki>.-</nowiki>',
'<!%-%-.-%-%->',
'<pre>.-</pre>',
'<syntaxhighlight.->.-</syntaxhighlight>',
'<source.->.-</source>', -- deprecated alias of syntaxhighlight tag
}
local template_skip = { -- templates to be skipped for whatever reason; mostly because they resemble cs1-like templates
['Citation-attribution'] = true,
}
local Article_content;
local anchor_id_list = {}; -- exported tables
local template_list = {};
local article_whitelist = {};
--[[--------------------------< A R T I C L E _ C O N T E N T _ G E T >----------------------------------------
get article content, remove certain html-like tags and their content so that this code doesn't include any citation
templates inside the tags as valid tagets; they are not.
]]
local function article_content_get ()
if not Article_content then
Article_content = mw.title.getCurrentTitle():getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
for _, tag in ipairs (patterns_tags) do
Article_content = Article_content:gsub (tag, ''); -- remove certain html-like tags and their content
end
end
end
--[[--------------------------< S F N R E F _ G E T >----------------------------------------------------------
make an anchor id from the contents of {{sfnref}} or {{harvid}}. this function assumes that {{sfnref}} and {{harvid}}
are correctly formed.
]]
local function sfnref_get (template)
template = template:gsub ('{{%s*(.-)%s*}}', '%1'); -- strip bounding template markup and trim
local parts = mw.text.split (template, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
local anchor_id = {};
if redirects_sfnref[parts[1]:lower()] then
anchor_id[1] = 'CITEREF';
else
return nil; -- not an sfnref or harvid template
end
local i = 2; -- indexer into parts{} table
local j = 2; -- indexer into anchor_id{} table which already has 'CITEREF' at [1]
while parts[i] and 7 > j do -- loop through what should be just positional parameters for names and year (2-6 four names and a date)
if not parts[i]:find ('=') then -- look for equal sign (named paraneter in a template that doesn't support named parameters)
anchor_id[j] = parts[i]; -- positional parameters are saved
j = j+1; -- bump the anchor_id{} indexer
end
i = i+ 1; -- bump the parts{} indexer
end
return table.concat (anchor_id, '');
end
--[[--------------------------< D A T E _ G E T >--------------------------------------------------------------
extract year from one of |year=, |date=, |publicationdate=, or |publication-date in that order. Does not error
check (that is left to the cs1|2 templates to do)
also gets date from |<date alias>={{date|...}}
]]
local function date_get (template, aliases)
local date;
local rvalue;
for _, pattern in ipairs (aliases) do -- spin through the date alias patterns
rvalue = tostring(template):match (pattern); -- is this |<date alias>= used (tostring() because something makes match() think template is a table)
if rvalue then
rvalue = tostring(template):match (pattern .. '(%b{})'); -- is rvalue a template?
if rvalue then
rvalue = rvalue:gsub ('{{%s*(.-)%s*}}', '%1'); -- strip bounding template markup and trim
local parts = mw.text.split (rvalue, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
if redirects_date[parts[1]:lower()] then -- if parts[1] names {{date}} or redirect
rvalue = parts[2]; -- assume that date template is properly formed, first positional parameter is the date
else
return ''; -- |date= holds some other template than {{date}} or redirect
end
else
rvalue = template:match (pattern .. '([^|}]+)');
if rvalue then -- if rvalue is something
rvalue = mw.text.trim (rvalue); -- trim it
end
if not rvalue or '' == rvalue then -- if rvale was nothing or trimed to nothing
rvalue = nil; -- ensure that it is unset so we can try the next parameter in the list
end
end
if rvalue then
for _, pattern in ipairs (patterns_date) do -- spin through the recognized date formats
date = rvalue:match (pattern); -- attempt to extract year portion according to the pattern
if date then
return date; -- matched so return;
end
end
break; -- found a date but it was malformed so abandon
end
end
end
return ''; -- no date param or date param doesn't hold a recognized date; empty string for concatenation
end
--[[--------------------------< V N A M E S _ G E T >----------------------------------------------------------
extract names from |vauthors= or |veditors=; there is no |vcontributors= parameter.
splits the v parameter value at the comma; correctly handles accept-as-witten markup when used to wrap a comma-
separated names (corporate)
]]
local function vnames_get (params, vparam)
local vnames = {}; -- first four author or editor names go here
local split = {}; -- temp table to assist in decoding accept-as-witten-markup
if params[vparam] then -- test for |vauthors= or |veditor=
split = mw.text.split (params[vparam], '%s*,%s*'); -- this will separate portions of ((Black, Brown, White, an Co.))
local i = 1; -- an indexer
while split[i] do
if split[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of comma-separated accept-as-witten; this segment has the opening doubled parens
local name = split[i];
i=i+1; -- bump indexer to next segment
while split[i] do
name = name .. ', ' .. split[i]; -- concatenate with previous segments
if split[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parens
break; -- and done reassembling so
end
i=i+1; -- bump indexer
end
table.insert (vnames, name); -- and add accept-as-witten name to the vnames table
else
table.insert (vnames, split[i]); -- and add name to the vnames table
end
i=i+1; -- bump indexer
if 5 == i then break; end -- limit to four names
end
for i, vname in ipairs (vnames) do
if not vname:match ('%(%(.-%)%)') then -- without accept-this-value-as-written markup
vnames[i] = vname:gsub ('(.-)%s+%u+$', '%1'); -- extract and save surname(s)
end
end
for i, vname in ipairs (vnames) do -- repeat, this time for accept-this-value-as-written markup
vnames[i] = vname:gsub ('%(%((.-)%)%)', '%1'); -- remove markup if present and save the whole name
end
end
return 0 ~= #vnames and table.concat (vnames) or nil -- return a concatenation of the vnames; nil else
end
--[[--------------------------< N A M E S _ G E T >------------------------------------------------------------
cs1|2 makes anchor id from contributor, author, or editor name-lists in that order
get the names from the cs1|2 template; if there are no contributor names, try author names, then try editor names.
returns concatenated names in enumeration order when successful; nil else
empty name (nameholding parameter n is present without value) and missing name (nameholding parameter n is not
present) are included as empty string with all other names
]]
local function names_get (params, aliases_list)
local names = {}; -- first four author or editor names go here
local enum_alias; -- alias with '#' replaced with a digit
for enum=1, 4 do -- four names only
for i, alias in ipairs (aliases_list) do
if not names[enum] then -- hanven't found a previous alias with this [enum]? see if we can find this alias with this enum
enum_alias = alias:gsub ('#', enum); -- replace '#' to make 'lastn'
if 1 == enum then -- because |last= and last1= are exact aliases
if params[enum_alias] then -- test |last1= first
names[enum] = params[enum_alias]; -- found so save the value assigned to |last1=
break; -- next enum
else
enum_alias = alias:gsub ('#', ''); -- replace '#' to make 'last'
if params[enum_alias] then
names[enum] = params[enum_alias]; -- found so save the value assigned to |last=
break; -- next enum
end
end
else -- here for enum 2, 3, 4
if params[enum_alias] then
names[enum] = params[enum_alias]; -- found so save the value assigned to |lastn=
break; -- next enum
end
end
end
end
end
for enum=1, 4 do -- spin through the names table and
local name = names[enum];
if not name then -- when nameholding parameter n is not present (nil)
name = ''; -- convert to empty string for concatenation
end
name = name:gsub('%(%((.-)%)%)', '%1'); -- remove accept-as-written markup if present
names[enum] = name; -- save the modified name
end
local name_str = table.concat (names); -- concatenate the names
return '' ~= name_str and name_str or nil; -- return the concatenation if not empty string; nil else
end
--[[--------------------------< T E M P L A T E _ S T R I P >--------------------------------------------------
removes the citation or havrc template's {{ and }} markup then removes, in whole, any templates found inside the
citation or harvc template.
Templates are not allowed in parameters that are made part of COinS metadata; yet, they will appear. cs1|2 does
not see the template markup but instead sees the result of the template as html. cs1|2 strips the html which
leaves the displayed value for the anchor id. We can't do that here so, because templates aren't allowed in
parameters, we simply discard any templates found in the cs1|2 template.
this may leave a |lastn= parameter empty which will be treated as if it were really empty as cs1|2 do (three authors,
|last2= empty -> CITEREFLast1Last3YYYY (the harv and sfn render: 'Last1, & Last3 YYYY' with CITEREFLast1Last3YYYY).
]]
local function template_strip (template)
template = template:gsub ('^{{%s*', ''):gsub ('%s*}}$', '', 1); -- remove outer {{ and }} (cs1|2 template delimiters with trailing/leading whitespace)
template = template:gsub ('%b{}', ''); -- remove any templates from the cs1|2 template
return template;
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other lua magic pattern characters
return argument;
end
--[=[-------------------------< W I K I L I N K _ S T R I P >--------------------------------------------------
Wikilink markup does not belong in an anchor id and can / does confuse the code that parses apart citation and
harvc templates so here we remove any wiki markup:
[[link|label]] -> label
[[link]] -> link
]=]
local function wikilink_strip (template)
for wikilink in template:gmatch ('%[%b[]%]') do -- get a wikilink
template = template:gsub ('%[%b[]%]', '__57r1P__', 1); -- install a marker
if wikilink:match ('%[%[.-|(.-)%]%]') then
wikilink = wikilink:match ('%[%[.-|(.-)%]%]'); -- extract label from complex [[link|label]] wikilink
else
wikilink = wikilink:match ('%[%[(.-)%]%]'); -- extract link from simple [[link]] wikilinks
end
wikilink = escape_lua_magic_chars (wikilink); -- in case there are lua magic characters in wikilink
template = template:gsub ('__57r1P__', wikilink, 1); -- replace the marker with the appropriate text
end
return template;
end
--[[--------------------------< T E M P L A T E _ N A M E _ G E T >--------------------------------------------
return the citation or harvc template's name; convert to lower case and trim leading and trailing whitespace;
when the template is a sandbox the subpage portion of the template name is omitted from the returned template name
{{Cite book/new |...}} returns cite book
]]
local function template_name_get (template)
local template_name = template:match ('^{{%s*([^/|}]+)'); -- get template name; ignore subpages ~/new, ~/sandbox; parser functions
if not template_name or template_name:match ('^#') then -- parser functions, magic words don't count as templates
return nil; -- could not get template name from (possibly corrupt) template; extraneous opening { mid template can cause this;
end;
template_name = template_name:gsub ('%s*$', ''); -- trim trailing whitespace; leading whitespace already removed
return Lang_obj:ucfirst (template_name); -- first character in template name must be uppercase (same as canonical template name) TODO: better way to do this?
end
--[[--------------------------< T E M P L A T E _ P A R A M S _ G E T >----------------------------------------
parse apart a template's parameters and store in the params table where key is the parameter's name and value is
the parameter's value; empty parameters are not saved
]]
local function template_params_get (template, params_t)
template = wikilink_strip (template); -- because piped wikilinks confuse code that builds params_t{} and because wikilinks not allowed in an anchor id
-- strip templates after getting |ref= value because |ref={{sfnref}} and |ref={{harvid}} are allowed
template = template_strip (template); -- because template markup can confuse code that builds params_t{} and because templates in name parameters are not allowed
local temp_t = mw.text.split (template, '%s*|%s*'); --split on the pipe
for _, param in ipairs (temp_t) do
if param:find ('=', 1, true) then -- a named parameter?
local k, v = param:match ('%s*([^=]-)%s*=%s*([^|}]+)');
if v then -- there must be a value
if '' ~= v and not v:match ('^%s$') then -- skip when value is empty string or only whitespace
params_t[k] = mw.text.trim (v); -- add trimmed value else
end
end
end
end
end
--[[--------------------------< C I T E R E F _ M A K E _ H A R V C >------------------------------------------
makes anchor_id from {{harvc}} or redirects
]]
local function anchor_id_make_harvc (template)
local date = date_get (template, alias_patterns_harvc_date); -- get date; done here because might be in {{date}}; return date if valid; empty string else
local anchor_id;
local params = {}; -- table of harvc parameters
local id; -- custom anchor id for this {{harvc}} template
id = template:match ('|%s*id%s*=%s*(%b{})'); -- in case |id={{sfnref}}; done here because templates will be stripped
template_params_get (template, params); -- build a table of template parameters and their values; this strips wikilinks and templates
if id then -- when set is {{sfnref}} or {{harvid}} template
return sfnref_get (id); -- returns content of {{sfnref}} or {{harvid}}; nil else
end
if params.id then -- custom anchor for this {{harvc}} template (text)
return params.id; -- |id= value as written
end
anchor_id = names_get (params, aliases_harvc_author); -- get the harvc contributor names
if anchor_id then -- if names were gotten
return 'CITEREF' .. anchor_id .. date;
end
return nil; -- no names; no anchor_id
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ W R A P P E R >----------------------------------
for wrapper templates
inspect externally visible |ref= to decide what to do:
|ref= - empty or missing: get names and date from whitelist defaults; override defaults from externally visible template parameters
|ref=harv - same as empty or missing
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
|ref={{Harvid|name|name|name|name|year}} - assemble an anchor id from {{harvid}} positional parameters
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
]]
local function anchor_id_make_wrapper (template)
local ref; -- content of |ref=
local template_name; -- name of the template
local anchor_id; -- the assembled anchor id from this template
local date;
local name_default;
local date_default;
local vol;
local params = {}; -- table of template parameters
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
end
date = date_get (template, alias_patterns_date); -- get date; done here because might be in {{date}}
-- if '' == date then
-- date = whitelist.wrapper_templates[template_name][2] or ''; -- no externally visible date so get default date
-- end
ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the wrapper template
if not ref then
if template:match ('|%s*ref%s*=([^|}]+)') then -- |ref={{template}} not found; if there is a |ref= param with an assigned value
ref = template:match ('|%s*ref%s*=([^|}]+)'); -- get the value; whitespace is a 'value'
if ref then -- nil when |ref=|... or when |ref=}} (no spaces between assignment operator and pipe or closing brace)
ref = mw.text.trim (ref); -- something, could be just whitespace, so trim leading / trailing whitespace
if '' == ref then -- trimming a string of whitespace makes an empty string
ref = nil; -- make empty ref same as missing ref
end
end
end
end
template_params_get (template, params); -- build a table of template parameters and their values
if whitelist.wrapper_templates[template_name][1] then -- is this wrapper a simple-default wrapper?
name_default = whitelist.wrapper_templates[template_name][1]; -- get the default names
date_default = whitelist.wrapper_templates[template_name][2]; -- get the default date
else
vol = params['volume'] or 'default';
if not whitelist.wrapper_templates[template_name][vol] then -- make sure this volume exists
vol = 'default'; -- doesn't exist, use default volume
end
name_default = whitelist.wrapper_templates[template_name][vol][1]; -- get the default names
date_default = whitelist.wrapper_templates[template_name][vol][2]; -- get the default date
end
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty
anchor_id = names_get (params, aliases_contributor) or -- get contributor, author, or editor names
names_get (params, aliases_author) or
vnames_get (params, 'vauthors') or -- |vauthors=
names_get (params, aliases_editor) or
vnames_get (params, 'veditors') or -- |veditors=
name_default; -- default names from whitelist
-- whitelist.wrapper_templates[template_name][1]; -- default names from whitelist
if '' == date then -- if date not provided in the template
date = date_default; -- use the default date from whitelist
end
if anchor_id then -- if names were gotten
anchor_id = 'CITEREF' .. anchor_id .. date;
end
elseif ref:match ('%b{}') then -- ref holds a template
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
elseif 'none' == ref then -- |ref=none
return nil; -- anchor id expicitly suppressed
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
end
return anchor_id; -- anchor_id text; nil else
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ C S 1 2 >----------------------------------------
for cs1|2 template and cs1-like templates
inspect |ref= to decide what to do:
|ref= - empty or missing: get names and date from template parameters; all cs1|2 create CITEREF anchor IDs
|ref=harv - get names and date from template parameters
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
|ref={{Harvid|name|name|name|name|year}} - assemble an anchor id from {{harvid}} positional parameters
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
]]
local function anchor_id_make_cs12 (template)
local ref; -- content of |ref=
local template_name; -- name of the template
local anchor_id; -- the assembled anchor id from this template
local date;
local params = {}; -- table of template parameters
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
end
if redirects_patent[template_name] then
date = date_get (template, alias_patterns_patent_date); -- get date; done here because might be in {{date}}
else
date = date_get (template, alias_patterns_date);
end
ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the cs1|2 template
if not ref then
if template:match ('|%s*ref%s*=([^|}]+)') then -- |ref={{template}} not found; if there is a |ref= param with an assigned value
ref = template:match ('|%s*ref%s*=([^|}]+)'); -- get the value; whitespace is a 'value'
if ref then -- nil when |ref=|... or when |ref=}} (no spaces between assignment operator and pipe or closing brace)
ref = mw.text.trim (ref); -- something, could be just whitespace, so trim leading / trailing whitespace
if '' == ref then -- trimming a string of whitespace makes an empty string
ref = nil; -- make empty ref same as missing ref
end
end
end
end
template_params_get (template, params); -- build a table of template parameters and their values
if not ref then -- |ref= not set, might be cite LSA which doesn't support |ref=
if 'cite lsa' == template_name then
return 'CITEREF' .. (params.last or '') .. (params.year or ''); -- cite LSA always creates an anchor id using only |last= and |year= (no aliases)
end
end
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty
if redirects_patent[template_name] then -- if this is a cite patent template
anchor_id = names_get (params, aliases_inventor); -- inventor names only
else -- cs1|2 template
anchor_id = names_get (params, aliases_contributor) or -- get contributor, author, or editor names
names_get (params, aliases_author) or
vnames_get (params, 'vauthors') or -- |vauthors=
names_get (params, aliases_editor) or
vnames_get (params, 'veditors'); -- |veditors=
end
if anchor_id then -- if names were gotten
anchor_id = 'CITEREF' .. anchor_id .. date;
end
elseif ref:match ('%b{}') then -- ref holds a template
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
elseif 'none' == ref and not redirects_patent[template_name] then -- |ref=none; not supported by cite patent
return nil; -- anchor id expicitly suppressed
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
end
return anchor_id; -- anchor_id text; nil else
end
--[[--------------------------< L I S T _ A D D >--------------------------------------------------------------
adds an <item> to <list> table; for anchor IDs, the boolean <encode> argument must be set true; no return value
]]
local function list_add (item, list, encode)
if item then -- if there was an item
if encode then -- for anchor IDs ...
item = mw.uri.anchorEncode (item); -- encode to remove wikimarkup, convert spaces to underscores etc
end
if not list[item] then -- if not already saved
list[item] = 1; -- save it
else -- here when this item already saved
list[item] = list[item] + 1; -- to indicate that there are multiple items
end
end
end
--[[--------------------------< A N C H O R _ I D _ M A K E _ A N C H O R >------------------------------------
make anchor IDs from {{anchor}}; there may be more than one because {{anchor}} is not limited to the number of
anchors it may hold.
]]
local function anchor_id_make_anchor (template, anchor_id_list)
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = wikilink_strip (template); -- strip any wikilink markup (there shouldn't be any but just in case)
local params = {};
local anchor_id;
for param in template:gmatch ('%b{}') do -- loop through the template; remove and save templates (presumed to be sfnref or harvid)
table.insert (params, param); -- save it
template = template:gsub ('%b{}', '', 1); -- remove it from source template
end
for _, t in ipairs (params) do -- spin through the templates in params
anchor_id = sfnref_get (t); -- attempt to decode {{sfnref}} and {{harvid}}
if anchor_id then -- nil when not {{sfnref}} or {{harvid}}
list_add (anchor_id, anchor_id_list, true); -- add anchor ID to the list
end
end
template = template:gsub ('|%s*|', '|'); -- when pipe follows pipe with or without white space, remove extraneous pipe
template = template:gsub ('^|', ''):gsub('|$', ''); -- remove extraneous leading and trailing pipes
params = mw.text.split (template, '%s*|%s*'); -- split at the pipe and remove extraneous space characters
for _, t in ipairs (params) do -- spin through the anchor IDs
anchor_id = mw.text.trim (t); -- trim white space
if '' ~= anchor_id then -- should always have something
list_add (anchor_id, anchor_id_list, true); -- add anchor ID to the list
end
end
end
--[[--------------------------< T E M P L A T E _ L I S T _ A D D >--------------------------------------------
makes a list of templates use in the article.
]]
local function template_list_add (template)
local template = template:match ('{{%s*(.-)[|}]'); -- keep the case of the template - this is different from template_name_get()
if template and not template:match ('^#') then -- found a template or magic word; ignore magic words
template=mw.text.trim (template); -- trim whitespace
template = Lang_obj:ucfirst (template); -- first character in template name must be uppercase (same as canonical template name) TODO: better way to do this?
list_add (template, template_list); -- add to list with (unused) tally
end
end
--[[--------------------------< A N C H O R _ I D _ L I S T _ M A K E >----------------------------------------
makes a list of anchor ids from cs1|2, cs1|2-like, vcite xxx, harvc, anchor, wikicite templates
Because cs1|2 wrapper templates can, and often do, hide the author and date parameters inside the wrapper,
these parameters are not available in the article's wikisource so {{harv}}, {{sfn}}, and {{harvc}} templates that
link correctly to those wrapper templates will incorrectly show error messages. Use |ignore-err=yes in the {{harv}},
{{sfn}}, and {{harvc}} templates to supress the error message.
creates a list of templates used in the article for use with the whitelist
creates a list of article-local whitelisted anchor IDs from {{sfn whitelist}}
]]
local function anchor_id_list_make ()
article_content_get (); -- attempt to get this article's content
if '' == Article_content then -- when there is no article content
return ''; -- no point in continuing
end
local template; -- place to hold the template that we found
local template_name;
local anchor_id; -- place to hold an anchor id as it is extracted / decoded
local find_pattern = '%f[{]{{[^{]';
local tstart, tend = Article_content:find (find_pattern); -- find the first template; do not find template variables: {{{template var|}}}
while tstart do
template = Article_content:match ('%b{}', tstart); -- get the whole template
if not template then
break; -- template is nil for some reason (last template missing closing }} for example) so declare ourselves done
end
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
template_list_add (template); -- add this template's name to the list
if data.known_templates_cs12 [template_name] then
anchor_id = anchor_id_make_cs12 (template); -- extract an anchor id from this template
list_add (anchor_id, anchor_id_list, true)
elseif data.known_templates_vcite [template_name] then
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the vcite template
if ref then -- |ref={{template}}
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
list_add (anchor_id, anchor_id_list, true);
else
local params = {};
template_params_get (template, params); -- build a table of template parameters and their values
anchor_id = params['ref']; -- when both set, vcite uses value from |ref=
if not anchor_id and params['harvid'] then
anchor_id = 'CITEREF' .. params['harvid']; -- in vcite, |harvid= auto-adds 'CITEREF' prefix to the value in |harvid=
end
list_add (anchor_id, anchor_id_list, true);
end
elseif data.known_templates_harvc [template_name] then
anchor_id = anchor_id_make_harvc (template); -- extract an anchor id from this template
list_add (anchor_id, anchor_id_list, true);
elseif data.known_templates_wikicite [template_name] then
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}}
if ref then
anchor_id = sfnref_get (ref);
elseif template:match ('|%s*ref%s*=([^|}]+)') then
anchor_id = template:match ('|%s*ref%s*=([^|}]+)'); -- plain-text
elseif template:match ('|%s*id%s*=%s*(%b{})') then
ref = template:match ('|%s*id%s*=%s*(%b{})');
anchor_id = 'Reference-' .. sfnref_get (ref);
elseif template:match ('|%s*id%s*=([^|}]+)') then
anchor_id = 'Reference-' .. template:match ('|%s*id%s*=([^|}]+)'); -- plain-text
else
anchor_id = nil; -- no matches, ensure that anchor_id has no value
end
if anchor_id then
list_add (anchor_id, anchor_id_list, true);
end
elseif data.known_templates_anchor [template_name] then
anchor_id_make_anchor (template, anchor_id_list); -- extract anchor ids from this template if any
elseif data.known_templates_sfn_whitelist [template_name] then
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = mw.text.trim (template, '%s|'); -- trim leading trailing white space and pipes
template = mw.text.split (template, '%s*|%s*'); -- make a table of the template's parameters
for _, anchor_id in ipairs (template) do -- spin through this template's parameter
if '' ~= anchor_id and not article_whitelist[anchor_id] then
anchor_id = mw.uri.anchorEncode (anchor_id)
article_whitelist[anchor_id] = 1; -- add to the whitelist
end
end
elseif template_name and whitelist.wrapper_templates[template_name] then
anchor_id = anchor_id_make_wrapper (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
elseif template_name and template_name:match ('^Cit[ea]') then -- not known, not known wrapper; last gasp, try as cs1-like
anchor_id = anchor_id_make_cs12 (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
end
tstart, tend = Article_content:find (find_pattern, tend); -- search for another template; begin at end of last search
end
mw.logObject (anchor_id_list, 'anchor_id_list');
mw.logObject (template_list, 'template_list');
mw.logObject (article_whitelist, 'article_whitelist');
return anchor_id_list;
end
--[[--------------------------< E X P O R T E D _ T A B L E S >------------------------------------------------
]]
return {
anchor_id_list = anchor_id_list_make(), -- table of anchor ids available in this article
article_whitelist = article_whitelist, -- table of anchor ids with false-positive error message to be suppressed
template_list = template_list, -- table of templates used in this article
}
9cf1091b65b65bfb32bb0aa2b73bb581d19e99f1
Module:Footnotes/anchor id list/data
828
104
224
223
2022-09-04T15:24:57Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- copied from Module:Ref info/data - maybe overkill here?
-- for this application make lists from the redirect lists and force all template names first character uppercase
require('Module:No globals');
--[[--------------------------< C S 1 _ T E M P L A T E _ P A T T E R N S >------------------------------------
These are patterns for cs1 templates and their redirects. These patterns exclude redirects that are vcite-like
which redirects should be deleted because vcite is not cs1.
]]
local cs1_template_patterns = { -- lua patterns of the cannonical names and redirects
'[Cc]ite ar[Xx]iv', -- arXiv is the canonical name
'[Cc]ite ArXiv',
'[Cc]ite AV media', -- canonical
'[Cc]ite audio', '[Cc]ite AV', '[Cc]ite AV ?Media', '[Cc]ite av media',
'[Cc]ite cd', '[Cc]ite DVD', '[Cc]ite dvd', '[Cc]ite film',
'[Cc]ite image', '[Cc]ite media', '[Cc]ite movie',
'[Cc]ite music video', '[Cc]ite radio', '[Cc]ite song',
'[Cc]ite ?video', '[Cc]ite visual', '[Cc]ite You[Tt]ube',
'[Cc]ita vídeo', -- non-English redirect; TODO: tally separately?
'[Cc]ite AV media notes', -- canonical
'[Cc]ite album[ %-]notes', '[Cc]ite av media notes',
'[Cc]ite DVD[ %-]notes', '[Cc]ite dvd%-notes', '[Cc]ite liner notes',
'[Cc]ite music release notes', '[Ll]iner notes',
'[Cc]ite bio[Rr]xiv', -- bioRxiv is the canonical form
'[Cc]ite [Bb]ook', -- book is the canonical form
'[Bb]ook cite', '[Bb]ook reference', '[Bb]ook reference url',
'[Cc] book', '[Cc]it book', '[Cc]ite books', '[Cc]ite chapter',
'[Cc]ite ebook', '[Cc]ite manual', '[Cc]ite page',
'[Cc]ite publication', '[Cc]ite score',
'[Cc]ite work', '[Cc]ite%-?book',
'[Bb]okref', '[Cc]itace monografie', '[Cc]itar livro', -- non-English redirects; TODO: tally separately?
'[Cc]iteer boek', '[Oo]uvrage', '[Rr]ef%-llibre', '서적 인용',
'[Cc]ite citeseerx', -- canonical
'[Cc]ite conference', -- canonical
'[Cc]ita conferenza', '[Cc]ite proceedings', '[Cc]onference reference', -- cita conferenza is non-English; TODO: tally separately?
'[Cc]ite ?encyclopedia', -- cite encyclopedia is the canonical name
'[Cc]ite contribution', '[Cc]ite dic', '[Cc]ite dictionary',
'[Cc]ite encyclopaedia', '[Cc]ite encyclopædia', '[Ee]ncyclopedia',
'[Cc]ite [Ee]pisode', -- episode is the canonical form
'[Cc]ite show',
'[Cc]ite interview', -- canonical
'[Cc]ite ?journal', -- cite journal is the canonical form
'[Cc] journal', '[Cc]itation journal', '[Cc]ite abstract',
'[Cc]ite document', '[Cc]ite Journal', '[Cc]ite journal zh',
'[Cc]ite ?paper', '[Vv]cite2 journal',
'[Cc]ita pubblicazione', '[Cc]itace periodika', '[Cc]itar jornal', -- non-English redirects; TODO: tally separately?
'[Cc]itar publicació', '[Cc]ytuj pismo', '[Tt]idskriftsref',
'Навод из стручног часописа', '저널 인용',
'[Cc]ite [Mm]agazine', -- magazine is the canonical form
'[Cc]ite mag', '[Cc]ite magazine article', '[Cc]ite newsletter',
'[Cc]ite periodical',
'[Cc]ite mailing ?list', -- mailing list is the canonical form
'[Cc]ite list',
'[Cc]ite maps?', -- map is the canonical form
'[Cc]ite[ %-]?news', -- cite news is the canonical form
'[Cc] news', '[Cc]it news', '[Cc]itation news', '[Cc]ite article',
'[Cc]ite n', '[Cc]ite new', '[Cc]ite newspaper', '[Cc]ite News',
'[Cc]ite news%-q', '[Cc]ite news2', '[Cc]itenewsauthor', '[Cc]ute news',
'[Cc]itar notícia', '[Hh]aber kaynağı', '[Tt]idningsref', 'استشهاد بخبر', -- non-English redirects; TODO: tally separately?
'뉴스 인용',
'[Cc]ite newsgroup', -- canonical
'[Cc]ite usenet',
'[Cc]ite podcast', -- canonical
'[Cc]ite [Pp]ress release', -- press release is the canonical form
'[Cc]ite media release', '[Cc]ite news release', '[Cc]ite pr',
'[Cc]ite press', '[Cc]ite press release\.', '[Cc]ite press[%-]?release',
'[Cc]ite report', -- canonical
'[Cc]ite serial', -- canonical
'[Cc]ite sign', -- canonical
'[Cc]ite plaque',
'[Cc]ite speech', -- canonical
'[Cc]ite ssrn', -- canonical
'[Cc]ite SSRN',
'[Cc]ite tech ?report', -- techreport is the canonical form
'[Cc]ite standard', '[Cc]ite technical report', '[Tt]echrep reference',
'[Cc]ite thesis', -- canonical
'[Cc]ite dissertation',
'[Cc]itar tese', -- non-English redirect; TODO: tally separately?
'[Cc]ite [Ww]eb', -- web is the canonical form
'[Cc] web', '[Cc]it web', '[Cc]ite blog', '[Cc]ite URL', '[Cc]ite url',
'[Cc]ite w', '[Cc]ite wb', '[Cc]ite we', '[Cc]ite web\.',
'[Cc]ite webpage', '[Cc]ite website', '[Cc]ite website article',
'[Cc]ite%-?web', '[Cc]itweb', '[Cc]w', '[Rr]ef web', '[Ww]eb citation',
'[Ww]eb cite', '[Ww]eb link', '[Ww]eb[ %-]reference', '[Ww]eblink',
'[Cc]hú thích web', '[Cc]ita web', '[Cc]itace elektronické monografie', -- non-English redirects; TODO: tally separately?
'[Cc]itat web', 'مرجع ويب', 'یادکرد وب', '웹 인용',
}
--[[--------------------------< C S 2 _ T E M P L A T E _ P A T T E R N S >------------------------------------
These are patterns for cs2 templates redirects.
]]
local cs2_template_patterns = { -- lua patterns of the cannonical names and redirects
'[Cc]itation',
'[Cc]ite', '[Cc]ite citation', '[Cc]ite study',
'[Cc]ite [Tt]echnical standard',
}
--[[--------------------------< V C I T E _ T E M P L A T E _ P A T T E R N S >--------------------------------
These are patterns for Vcite-family templates and their redirects.
]]
local vcite_template_patterns = {
'[Vv]cite book', -- canonical
'[Vv]ancite book', '[Vv]ancite report', '[Vv]cite encyclopedia',
'[Vv]cite report',
'[Vv]cite journal', -- canonical
'[Cc]it journal', '[Cc]it paper', '[Vv]ancite journal', '[Vv]cite paper',
'[Vv]cite news', -- canonical
'[Vv]ancite news',
'[Vv]cite web', -- canonical
'[Vv]ancite web',
}
--[[--------------------------< H A R V C _ T E M P L A T E _ P A T T E R N S >--------------------------------
These are patterns for the harvc template and its redirects.
]]
local harvc_template_patterns = {
'[Hh]arvc', -- canonical
'[Cc]itec',
}
--[[--------------------------< C S 1 _ L I K E _ T E M P L A T E _ P A T T E R N S >--------------------------
These are patterns for miscellaneous templates and their redirects that 'look like' cs1 templates (begin with cite ...)
Because they 'look like' cs1 templates they are handled as if they were cs1 templates. These templates are NOT
wrapper templates; names and dates are always to be extracted from the article instantiation of the template.
]]
local cs1_like_template_patterns = {
'[Cc]ite LSA', -- canonical
}
--[[--------------------------< W I K I C I T E _ T E M P L A T E _ P A T T E R N S >--------------------------
These are patterns for the wikicite template and its redirects.
]]
local wikicite_template_patterns = {
'[Ww]ikicite', -- canonical
}
--[[--------------------------< A N C H O R _ T E M P L A T E _ P A T T E R N S >------------------------------
These are patterns for the anchor template and its redirects.
]]
local anchor_template_patterns = {
'[Aa]nchors?', -- anchor is canonical form
'[Aa]nchor for redirect',
'[Aa]nchro',
'[Aa]ncor',
}
--[[--------------------------< S F N _ W H I T E L I S T _ P A T T E R N S >----------------------------------
These are patterns for the anchor template and its redirects.
]]
local sfn_whitelist_patterns = {
'[Ss]fn whitelist', -- canonical
'[Hh]arv whitelist',
}
--[[--------------------------< K N O W N _ T E M P L A T E S >------------------------------------------------
These tables are created from the *_template_patterns tables. To make these tables, entries in the source tables
are evaluated to replace lua patterns with the appropriate characters to create names for the output tables.
First charqacter is always uppercase
For example:
[Cc]ite ar[Xx]iv
becomes
Cite arXiv
Cite arxiv
]]
local known_templates_cs12 = {}; -- the exported tables
local known_templates_vcite = {};
local known_templates_harvc = {};
local known_templates_wikicite = {};
local known_templates_anchor = {};
local known_templates_sfn_whitelist = {};
local function add_stripped (list, name)
if not list[name] then
list[name] = true;
end
end
local function pattern_convert (pattern, list)
local lead, tail, c, l, name;
local first_char_patterns = {
'^%[(%a)%a%]', -- leading character (usually uppercase)
'^%[%a(%a)%]', -- leading character (usually lowercase)
}
c = tostring (pattern:match ('%u')); -- tostring() required because I don't know why; lua chokes complaining that c is not a string
name = pattern:gsub ('^%[%a%a%]', c); -- replace bracketed first character [Xx] with selected character from the match
if name:match ('(.-)%[(%a)(%a)%](.*)') then -- mixed case optional letters
lead, c, l, tail = name:match ('(.-)%[(%a)(%a)%](.*)');
add_stripped (list, lead .. c .. tail); -- uppercase
add_stripped (list, lead .. l .. tail); -- lowercase
elseif name:match ('^([^%[]+)(%[ %%%-%]%?)(.+)$') then -- [ %-]?
lead, c, tail = name:match ('^([^%[]+)(%[ %%%-%]%?)(.+)$');
add_stripped (list, lead .. tail); -- neither char
add_stripped (list, lead .. ' ' .. tail); -- space
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%[]+)(%[%%%-%]%?)(.+)$') then -- [%-]?
lead, c, tail = name:match ('^([^%[]+)(%[%%%-%]%?)(.+)$');
add_stripped (list, lead .. tail); -- no hyphen
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%[]+)(%[ %%%-%])(.+)$') then -- [ %-]
lead, c, tail = name:match ('^([^%[]+)(%[ %%%-%])(.+)$');
add_stripped (list, lead .. ' ' .. tail); -- space
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^([^%?]+)(%%%-%?)(.+)$') then -- %-?
lead, c, tail = name:match ('^([^%?]+)(%%%-%?)(.+)$');
add_stripped (list, lead .. tail); -- no hyphen
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^(.-)(%%%-)(.+)$') then -- %-
lead, c, tail = name:match ('^(.-)(%%%-)(.+)$');
add_stripped (list, lead .. '-' .. tail); -- hyphen
elseif name:match ('^(.-)(.)%?(.*)$') then -- .?
lead, c, tail = name:match ('^(.-)(.)%?(.*)$');
add_stripped (list, lead .. tail); -- no character
add_stripped (list, lead .. c .. tail); -- character
else
add_stripped (list, name); -- no patterns so save as is
end
end
for _, t in ipairs ({
{cs1_template_patterns, known_templates_cs12},
{cs2_template_patterns, known_templates_cs12},
{cs1_like_template_patterns, known_templates_cs12},
{vcite_template_patterns, known_templates_vcite},
{harvc_template_patterns, known_templates_harvc},
{wikicite_template_patterns, known_templates_wikicite},
{anchor_template_patterns, known_templates_anchor},
{sfn_whitelist_patterns, known_templates_sfn_whitelist},
}) do
for _, pattern in ipairs (t[1]) do -- for each patern in *_template_patterns
pattern_convert (pattern, t[2]) -- convert and store in known_templates_*
end
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return
{
known_templates_anchor = known_templates_anchor,
known_templates_cs12 = known_templates_cs12,
known_templates_harvc = known_templates_harvc,
known_templates_vcite = known_templates_vcite,
known_templates_wikicite = known_templates_wikicite,
known_templates_sfn_whitelist = known_templates_sfn_whitelist,
}
6267b1029a020fb98adfa02a74118ae31897ac81
Module:Footnotes/whitelist
828
105
226
225
2022-09-04T15:24:58Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[--------------------------< W R A P P E R _ T E M P L A T E _ D E F A U L T S >----------------------------
A list of wrapper templates by their canonical names – spelling and capitalization is important. Each wrapper
template has a table of two values: [1] is the wrapper's default name-list as it is used in an anchor ID; [2] is
the default year. This table is indexed indirectly through the wrapper_templates table.
This table is not available externally.
]]
local wrapper_template_defaults = { -- keys are canonical template names
['Americana'] = {'Rines', '1920'}, -- tables with default name and default year
['Cite EB1911'] = {'Chisholm', '1911'}, -- tables with default name and default year
['EB1911'] = {'Chisholm', '1911'},
['EI3'] = {'FleetKrämerMatringeNawas', ''},
['ODNB'] = {'', ''}, -- there is no default anchor ID; this forces evaluation of {{cite ODNB}} redirects
}
--[[--------------------------< W R A P P E R _ T E M P L A T E _ D E F A U L T S _ V O L >--------------------
For wrapper templates that use |volume= to specify default name (often editor names) and year. Wrapper templates
are indexed by their canonical names – spelling and capitalization is important. Each wrapper template has a table
of values for every volume. Volumes may be indexed by Arabic or Roman numerals. Each volume index has a table of
twp values" [1] is the wrapper's default name-list as it is used in an anchor ID; [2] is the default year. Each
wrapper template in this table must have a ['default'] key for those occasions when |volume= is omitted or empty.
This table is indexed indirectly through the wrapper_templates table.
This table is not available externally.
]]
local wrapper_template_defaults_vol = { -- primary keys are canonical template names; TODO: do these keys have to be canonical template names?
['Cite Catholic Encyclopedia'] = { -- secondary keys are volume
['1'] = {'Herbermann', '1907'},
['2'] = {'Herbermann', '1907'},
['3'] = {'Herbermann', '1908'},
['4'] = {'Herbermann', '1908'},
['5'] = {'Herbermann', '1909'},
['6'] = {'Herbermann', '1909'},
['7'] = {'Herbermann', '1910'},
['8'] = {'Herbermann', '1910'},
['9'] = {'Herbermann', '1910'},
['10'] = {'Herbermann', '1911'},
['11'] = {'Herbermann', '1911'},
['12'] = {'Herbermann', '1911'},
['13'] = {'Herbermann', '1912'},
['14'] = {'Herbermann', '1912'},
['15'] = {'Herbermann', '1912'},
['default'] = {'Herbermann', '1913'},
},
['Cite EB9'] = {
['1'] = {'Baynes', '1878'}, ['I'] = {'Baynes', '1878'},
['2'] = {'Baynes', '1878'}, ['II'] = {'Baynes', '1878'},
['3'] = {'Baynes', '1878'}, ['III'] = {'Baynes', '1878'},
['4'] = {'Baynes', '1878'}, ['IV'] = {'Baynes', '1878'},
['5'] = {'Baynes', '1878'}, ['V'] = {'Baynes', '1878'},
['6'] = {'Baynes', '1878'}, ['VI'] = {'Baynes', '1878'},
['7'] = {'Baynes', '1878'}, ['VII'] = {'Baynes', '1878'},
['8'] = {'Baynes', '1878'}, ['VIII'] = {'Baynes', '1878'},
['9'] = {'Baynes', '1879'}, ['IX'] = {'Baynes', '1879'},
['10'] = {'Baynes', '1879'}, ['X'] = {'Baynes', '1879'},
['11'] = {'BaynesSmith', '1880'}, ['XI'] = {'BaynesSmith', '1880'},
['12'] = {'BaynesSmith', '1881'}, ['XII'] = {'BaynesSmith', '1881'},
['13'] = {'BaynesSmith', '1881'}, ['XIII'] = {'BaynesSmith', '1881'},
['14'] = {'BaynesSmith', '1882'}, ['XIV'] = {'BaynesSmith', '1882'},
['15'] = {'BaynesSmith', '1883'}, ['XV'] = {'BaynesSmith', '1883'},
['16'] = {'BaynesSmith', '1883'}, ['XVI'] = {'BaynesSmith', '1883'},
['17'] = {'BaynesSmith', '1884'}, ['XVII'] = {'BaynesSmith', '1884'},
['18'] = {'BaynesSmith', '1885'}, ['XVIII'] = {'BaynesSmith', '1885'},
['19'] = {'BaynesSmith', '1885'}, ['XIX'] = {'BaynesSmith', '1885'},
['20'] = {'BaynesSmith', '1886'}, ['XX'] = {'BaynesSmith', '1886'},
['21'] = {'BaynesSmith', '1886'}, ['XXI'] = {'BaynesSmith', '1886'},
['22'] = {'BaynesSmith', '1887'}, ['XXII'] = {'BaynesSmith', '1887'},
['23'] = {'BaynesSmith', '1888'}, ['XXIII'] = {'BaynesSmith', '1888'},
['24'] = {'BaynesSmith', '1888'}, ['XXIV'] = {'BaynesSmith', '1888'},
['default'] = {'Baynes', '1875–1889'},
},
['Encyclopaedia of Islam, New Edition'] = {
['1'] = {'GibbKramersLévi-ProvençalSchacht', '1960'},
['2'] = {'LewisPellatSchacht', '1965'},
['3'] = {'LewisMénagePellatSchacht', '1971'},
['4'] = {'van_DonzelLewisPellatBosworth', '1978'},
['5'] = {'Bosworthvan_DonzelLewisPellat', '1986'},
['6'] = {'Bosworthvan_DonzelPellat', '1991'},
['7'] = {'Bosworthvan_DonzelHeinrichsPellat', '1993'},
['8'] = {'Bosworthvan_DonzelHeinrichsLecomte', '1995'},
['9'] = {'Bosworthvan_DonzelHeinrichsLecomte', '1997'},
['10'] = {'BearmanBianquisBosworthvan_Donzel', '2000'},
['11'] = {'BearmanBianquisBosworthvan_Donzel', '2002'},
['12'] = {'BearmanBianquisBosworthvan_Donzel', '2004'},
['atlas'] = {'Brice', '1981'},
['abridged'] = {'van_Donzel', '1994'},
['default'] = {'BearmanBianquisBosworthvan_Donzel', '1960–2005'},
},
['New Cambridge Medieval History'] = {
['1'] = {'Fouracre', '2005'},
['2'] = {'McKitterick', '1995'},
['3'] = {'Reuter', '2000'},
['4a'] = {'LuscombeRiley-Smith', '2004'},
['4b'] = {'LuscombeRiley-Smith', '2004'},
['5'] = {'Abulafia', '1999'},
['6'] = {'Jones', '2000'},
['7'] = {'Allmand', '1998'},
['default'] = {'', '1995–2005'},
},
['The History of al-Tabari'] = {
['1'] = {'Rosenthal', '1989'},
['2'] = {'Brinner', '1986'},
['3'] = {'Brinner', '1991'},
['4'] = {'Perlmann', '1987'},
['5'] = {'Bosworth', '1999'},
['6'] = {'WattMcDonald', '1989'},
['7'] = {'McDonald', '1987'},
['8'] = {'Fishbein', '1997'},
['9'] = {'Poonawala', '1990'},
['10'] = {'Donner', '1993'},
['11'] = {'Blankinship', '1993'},
['12'] = {'Friedmann', '1992'},
['13'] = {'Juynboll', '1989'},
['14'] = {'Smith', '1994'},
['15'] = {'Humphreys', '1990'},
['16'] = {'Brockett', '1997'},
['17'] = {'Hawting', '1996'},
['18'] = {'Morony', '1987'},
['19'] = {'Howard', '1990'},
['20'] = {'Hawting', '1989'},
['21'] = {'Fishbein', '1990'},
['22'] = {'Rowson', '1989'},
['23'] = {'Hinds', '1990'},
['24'] = {'Powers', '1989'},
['25'] = {'Blankinship', '1989'},
['26'] = {'Hillenbrand', '1989'},
['27'] = {'Williams', '1985'},
['28'] = {'McAuliffe', '1995'},
['29'] = {'Kennedy', '1990'},
['30'] = {'Bosworth', '1989'},
['31'] = {'Fishbein', '1992'},
['32'] = {'Bosworth', '1987'},
['33'] = {'Bosworth', '1991'},
['34'] = {'Kraemer', '1989'},
['35'] = {'Saliba', '1985'},
['36'] = {'Waines', '1992'},
['37'] = {'Fields', '1987'},
['38'] = {'Rosenthal', '1985'},
['39'] = {'Landau-Tasseron', '1998'},
['40'] = {'Popovkin', '2007'},
['default'] = {'Yarshater', '1985–2007'},
},
}
--[[--------------------------< W R A P P E R _ T E M P L A T E S >--------------------------------------------
A list of wrapper templates and their redirects – spelling and capitalization is important; first character is
always uppercase. Each wrapper template gets its value from a k/v pair in the wrapper_template_defaults table.
article reader queries this table to see if template_name is a wrapper template
]]
local wrapper_templates = { -- keys are names of wrapper templates and their redirects
['Americana'] = wrapper_template_defaults['Americana'], -- canonical name; this template calls Cite Americana
['Catholic Encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['1913Catholic'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Catholic'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Catholic encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CatholicEncyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CE13'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CE1913'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite Americana'] = wrapper_template_defaults['Americana'], -- canonical name
['Cite Catholic Encyclopedia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['CathEncy'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite Catholic Encyclopædia'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite CE1913'] = wrapper_template_defaults_vol['Cite Catholic Encyclopedia'],
['Cite EB1911'] = wrapper_template_defaults['Cite EB1911'], -- canonical name
['1911EB'] = wrapper_template_defaults['Cite EB1911'], -- redirects
['EB1911 cite'] = wrapper_template_defaults['Cite EB1911'],
['Wikisource1911Enc Citation'] = wrapper_template_defaults['Cite EB1911'],
['Wikisource1911Enc citation'] = wrapper_template_defaults['Cite EB1911'],
['Cite EB9'] = wrapper_template_defaults_vol['Cite EB9'], -- canonical
['Eb9'] = wrapper_template_defaults_vol['Cite EB9'],
['Cite ODNB'] = wrapper_template_defaults['ODNB'], -- canonical
['Cite odnb'] = wrapper_template_defaults['ODNB'],
['DNBweb'] = wrapper_template_defaults['ODNB'],
['OBDNweb'] = wrapper_template_defaults['ODNB'],
['ODNB'] = wrapper_template_defaults['ODNB'],
['ODNBref'] = wrapper_template_defaults['ODNB'],
['ODNBweb'] = wrapper_template_defaults['ODNB'],
['EB1911'] = wrapper_template_defaults['EB1911'], -- canonical name; this template calls Cite EB1911
['1911'] = wrapper_template_defaults['EB1911'], -- redirects
['1911s'] = wrapper_template_defaults['EB1911'],
['Britannica 1911'] = wrapper_template_defaults['EB1911'],
['Encyclopedia Britannica 1911'] = wrapper_template_defaults['EB1911'],
['Encyclopædia Britannica 1911'] = wrapper_template_defaults['EB1911'],
['EB9'] = wrapper_template_defaults_vol['Cite EB9'], -- canonical; this template calls Cite EB9
['Encyclopaedia of Islam, New Edition'] = wrapper_template_defaults_vol['Encyclopaedia of Islam, New Edition'], -- canonical
['EI2'] = wrapper_template_defaults_vol['Encyclopaedia of Islam, New Edition'],
['Encyclopaedia of Islam, THREE'] = wrapper_template_defaults['EI3'], -- canonical
['EI3'] = wrapper_template_defaults['EI3'],
['New Cambridge Medieval History'] = wrapper_template_defaults_vol['New Cambridge Medieval History'], -- canonical
['The History of al-Tabari'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- canonical
['The History of Al-Tabari'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- redirects
['The History of al-Ṭabarī'] = wrapper_template_defaults_vol['The History of al-Tabari'], -- redirects
}
--[[--------------------------< T E M P L A T E _ N A M E S >--------------------------------------------------
This table holds the names of templates and the names of their redirects. Template names must be written exactly
as they are named at their templatespace page. This same also applies to redirects.
The indexes in this table are not critical but should be short and concise.
]]
local template_names = {
['ADB'] = {'Allgemeine Deutsche Biographie', 'Cite ADB'},
['Butt_Stations'] = {'Butt-Stations', 'Butt-stations'},
['Cam_Hist_Iran'] = {'Cambridge History of Iran', 'The Cambridge History of Iran'},
['DNB'] = {'Cite DNB', 'DNB', 'DNB Cite', 'Cite DNBSupp', 'DNBSupp', 'Cite DNB12', 'Cite DNBIE', 'DNB12', 'DNBIE', 'DNBfirst'},
['ME-ref'] = {'ME-ref', 'Me-ref'},
['ODB'] = {'ODB', 'Oxford Dictionary of Byzantium'},
['ODLA'] = {'ODLA', 'Oxford Dictionary of Late Antiquity'},
['NDB'] = {'Cite NDB', 'NDB'},
['Iranica'] = {'Encyclopædia Iranica Online', 'Encyclopædia Iranica', 'Encyclopaedia Iranica', 'Cite Encyclopædia Iranica Online'},
}
--[[--------------------------< S P E C I A L _ P A T T E R N S >----------------------------------------------
Lua patterns. These are scanned sequentially which costs time and processing far and above the time and processing
needed to index into whitelist{}. Do not create a pattern here if a normal whitelist entry or entries can be created.
]]
local special_patterns = {
'CITEREFACAD%u%u%u?%u?%d+%u%u?', -- {{Acad}} ID appears to be 2-4 letters, then 3 numbers, then 1-2 letters
'CITEREFAHD%d+', -- {{Cite AHD}}
'CITEREFHistoric_England%d+', -- {{National Heritage List for England}} & {{PastScape}}
'CITEREFHistoric_Environment_Scotland%u%u%u?%u?%d', -- {{Historic Environment Scotland}} %u can be BTL, GLD, HMPA, LB, SM
'CITEREFQHR%d+', -- {{Cite QHR}}
'CITEREF[%d%a_%pöüäß→]+_at_Bach_Digital', -- {{BDh}}
'CITEREF[BR]GBl_[12]%d%d%d%-?I?I?%/%d+', -- {{Cite Austrian gazette}}
'CITEREFStGBl_[12]%d%d%d%/%d+', -- {{Cite Austrian gazette}}
'CITEREFGBlÖ_[12]%d%d%d%/%d+', -- {{Cite Austrian gazette}}
}
--[[--------------------------< D N B _ S P E C I A L _ P A T T E R N S >--------------------------------------
Lua patterns. Note at special_patterns applies. These for the DNB templates only; these will be tried only when
there is a DNB template in the article.
Pretty much any author name during the period 1885–1901 inclusive, and 1912.
The DNBIE was published in 1903, and Template:DNBIE says that its use is deprecated, but we do not fight that battle here.
]]
local DNB_special_patterns = {
'CITEREF%a[%a%-_\']*188[5-9]', -- 1885–1889
'CITEREF%a[%a%-_\']*189%d', -- 1890–1899
'CITEREF%a[%a%-_\']*190[0-1]', -- 1900–1901
'CITEREF%a[%a%-_\']*1903', -- 1903 IE
'CITEREF%a[%a%-_\']*1912', -- 1912 supplement
}
--[[--------------------------< W H I T E L I S T >------------------------------------------------------------
This is a list of anchor IDs known to be associated with specific wrapper templates. The anchor ID serves as an
index into the table. The assigned value is another table that lists the associated template and any redirects.
Except for year disambiguators, anchor IDs must have the same form as the anchor creator makes; must be the
anchor-encoded form. Remove the year disambiguator.
Template names must be written exactly as they are named at their templatespace page. This same also applies to
redirects. Module:Footnotes reads the template names left to right so most-commonly-used template or redirect name
should appear first. When there are more than one name and when those templates have various anchor IDs the template
namelist should be added to the template_names{} table.
Note that references to Template:EB1911 are listed under "E" in the alphabetical list below to keep them organized.
]]
local whitelist = {
----------< # >----------
['CITEREF2013_Statistical_Yearbook_of_the_Republic_of_Croatia'] = {'Croatia Yearbook 2013'},
----------< A >----------
['CITEREFAGA_1884–1897'] = {'Schubert\'s compositions (references)'},
['CITEREFATOC2009'] = {'ATOCConnectingCommunitiesReportS10'},
['CITEREFAbaevBailey1985'] = template_names['Iranica'],
['CITEREFAbbas1988'] = template_names['Iranica'],
['CITEREFAbbas1989'] = template_names['Iranica'],
['CITEREFAbramowitzStegun1983'] = {'Abramowitz Stegun ref'},
['CITEREFActa_Lipsiensium1723'] = {'Bach\'s compositions (sources)'},
['CITEREFAdamsFranzosa2009'] = {'Adams Franzosa Introduction to Topology Pure and Applied'},
['CITEREFAdaschErnstKeim1978'] = {'Adasch Topological Vector Spaces'},
['CITEREFAffleck1978'] = {'Affleck-On Track'},
['CITEREFAhlgrimm1969'] = {'Bach\'s compositions (sources)'},
['CITEREFAhmadiNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFAhrons1927'] = {'Book-Ahrons-British Steam Railway Locomotive'},
['CITEREFAl-Kindi1912'] = {'The Governors and Judges of Egypt'},
['CITEREFAlbert_Schumann1886'] = {'Cite ADB'},
['CITEREFAlden1916'] = {'Shakespeare sonnets bibliography'},
['CITEREFAldrich1969'] = {'Aldrich-LocosGER7'},
['CITEREFAleksidze2018'] = template_names['ODLA'],
['CITEREFAlexiou2010'] = {'Cite flatiron'},
['CITEREFAlgar1983'] = template_names['Iranica'],
['CITEREFAlgar1989'] = template_names['Iranica'],
['CITEREFAlgar1990'] = template_names['Iranica'],
['CITEREFAlgar2003'] = template_names['Iranica'],
['CITEREFAlizadeh1990'] = template_names['Iranica'],
['CITEREFAllamaniPanagiotopoulou1978'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFAllcockDaviesle_FlemingMaskelyne1968'] = {'RCTS-LocosGWR-1'},
['CITEREFAllenBoddyBrownFry1970'] = {'RCTS-LocosLNER-8A'},
['CITEREFAllenBoddyBrownFry1971'] = {'RCTS-LocosLNER-8B'},
['CITEREFAllenBoddyBrownFry1983'] = {'RCTS-LocosLNER-8A'},
['CITEREFAmanat1998'] = template_names['Iranica'],
['CITEREFAmanat1999'] = template_names['Iranica'],
['CITEREFAmbartsumian2014'] = template_names['Iranica'],
['CITEREFAmerican_Railway_Association1922'] = {'1922 Locomotive Cyclopedia'},
['CITEREFAnderson1952'] = {'Naval Wars in the Levant 1559–1853'},
['CITEREFAndo2000'] = template_names['Iranica'],
['CITEREFAngelov2018'] = template_names['ODLA'],
['CITEREFAnwārEIr1985'] = template_names['Iranica'],
['CITEREFArkhangel'skiiPonomarev1984'] = {'Arkhangel\'skii Ponomarev Fundamentals of General Topology Problems and Exercises'},
['CITEREFArrey_von_Dommer1875'] = {'Cite ADB'},
['CITEREFAshraf2006'] = template_names['Iranica'],
['CITEREFAslanianBerberian2009'] = template_names['Iranica'],
['CITEREFAsmus1966'] = template_names['NDB'],
['CITEREFAsmussen1985'] = template_names['Iranica'],
['CITEREFAspreas1929'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFAtkins2007'] = {'Shakespeare sonnets bibliography'},
['CITEREFAube2011'] = template_names['Iranica'],
['CITEREFAudiKondevWangHuang2017'] = {'NUBASE2016'},
['CITEREFAvdoyan2018'] = template_names['ODLA'],
['CITEREFAwdry1990'] = {'Awdry-RailCo', 'Carnarvonshire Railway'},
['CITEREFAzarnoosh2021'] = template_names['Iranica'],
['CITEREFRamelli2018'] = {'Oxford Dictionary of Late Antiquity'},['CITEREFA_History_of_the_Crusades'] = {'Setton-A History of the Crusades'},
----------< B >----------
['CITEREFBabinger1962'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBabinger1978'] = {'Mehmed the Conqueror and His Time'},
['CITEREFBabinger1992'] = {'Mehmed the Conqueror and His Time'},
['CITEREFBachAgricola1754'] = {'Bach\'s compositions (sources)'},
['CITEREFBadura-SkodaBranscombe2008'] = {'Schubert\'s compositions (references)'},
['CITEREFBahramianHirtensteinGholami2013'] = {'Encyclopaedia Islamica'},
['CITEREFBalcer1990'] = template_names['Iranica'],
['CITEREFBaldwin1969'] = {'Setton-A History of the Crusades'},
['CITEREFBaldwin1985'] = {'Setton-A History of the Crusades'},
['CITEREFBaldwinKazhdan1991'] = template_names['ODB'],
['CITEREFBaldwinTalbot1991'] = template_names['ODB'],
['CITEREFBaltzer1916'] = {'Baltzer-Kolonialbahnen'},
['CITEREFBanach1932'] = {'Banach Théorie des Opérations Linéaires'},
['CITEREFBandy2021'] = template_names['Iranica'],
['CITEREFBartusis1991'] = template_names['ODB'],
['CITEREFBaxter1971'] = {'Baxter-BritishLocoCat1'},
['CITEREFBaxter1977'] = {'Baxter-BritishLocoCat1'},
['CITEREFBaxter1978'] = {'Baxter-BritishLocoCat2A'},
['CITEREFBaxter1979'] = {'Baxter-BritishLocoCat2B'},
['CITEREFBaxter1982'] = {'Baxter-BritishLocoCat3A', 'Baxter-BritishLocoCat3B'},
['CITEREFBaxter1984'] = {'Baxter-BritishLocoCat4'},
['CITEREFBaxter1986'] = {'Baxter-BritishLocoCat5A'},
['CITEREFBaxter1988'] = {'Baxter-BritishLocoCat5B'},
['CITEREFBaxter2012'] = {'Baxter-BritishLocoCat6'},
['CITEREFBeattie1986'] = template_names['Iranica'],
['CITEREFBeißwenger1991'] = {'Bach\'s compositions (sources)'},
['CITEREFBek2001'] = {'Cite Grove'},
['CITEREFBelke1996'] = {'Tabula Imperii Byzantini'},
['CITEREFBelkeMersisch1990'] = {'Tabula Imperii Byzantini'},
['CITEREFBelkeRestle1984'] = {'Tabula Imperii Byzantini'},
['CITEREFBellini2008'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBernardini2003'] = template_names['Iranica'],
['CITEREFBernhard_von_Poten1889'] = template_names['ADB'],
['CITEREFBernhard_von_Poten1898'] = template_names['ADB'],
['CITEREFBernjian2008'] = {'Encyclopaedia Islamica'},
['CITEREFBezilla1980'] = {'Bezilla-PRR-Electric-Traction'},
['CITEREFBianquis1998'] = {'The Cambridge History of Egypt', 'Cambridge History of Egypt'},
['CITEREFBickerman1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBierstedt1988'] = {'Bierstedt An Introduction to Locally Convex Inductive Limits'},
['CITEREFBiran2009'] = template_names['Iranica'],
['CITEREFBirken1976'] = {'Die Provinzen des Osmanischen Reiches'},
['CITEREFBivar1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBivar2003'] = template_names['Iranica'],
['CITEREFBlair2002'] = template_names['Iranica'],
['CITEREFBlair2021'] = template_names['Iranica'],
['CITEREFBlake1966'] = {'DisraeliRef'},
['CITEREFBlanken2019'] = {'Bach\'s compositions (sources)'},
['CITEREFBlankinship1994'] = {'The End of the Jihâd State', 'The End of the Jihad State'},
['CITEREFBlautSchulze2008'] = {'Bach\'s compositions (sources)'},
['CITEREFBloom2007'] = {'Cite Routledge Broadway', 'Cite Broadway Routledge', 'Cite Routledge Guide to Broadway', 'Routledge Guide to Broadway'},
['CITEREFBock1978'] = {'Audie-bock-directors'},
['CITEREFBoddyBrownFryHennigan1968'] = {'RCTS-LocosLNER-4'},
['CITEREFBoddyBrownFryHennigan1975'] = {'RCTS-LocosLNER-2B'},
['CITEREFBoddyBrownFryHennigan1977'] = {'RCTS-LocosLNER-9A', 'RCTS-LocosLNER-9B'},
['CITEREFBoddyBrownFryHennigan1979'] = {'RCTS-LocosLNER-3A'},
['CITEREFBoddyBrownHenniganHoole1984'] = {'RCTS-LocosLNER-6C'},
['CITEREFBoddyBrownHenniganNeve1981'] = {'RCTS-LocosLNER-3B'},
['CITEREFBoddyBrownNeveYeadon1983'] = {'RCTS-LocosLNER-6B'},
['CITEREFBoddyFryHenniganHoole1990'] = {'RCTS-LocosLNER-10B'},
['CITEREFBoddyFryHenniganProud1963'] = {'RCTS-LocosLNER-1'},
['CITEREFBoddyNeveTeeYeadon1982'] = {'RCTS-LocosLNER-6A'},
['CITEREFBoddyNeveYeadon1973'] = {'RCTS-LocosLNER-2A'},
['CITEREFBody1989'] = {'Body-Railways-Vol2'},
['CITEREFBon1969'] = {'La Morée franque'},
['CITEREFBonebakker1997'] = template_names['Iranica'],
['CITEREFBonner2010'] = {'New Cambridge History of Islam'},
['CITEREFBonnett2005'] = {'Bonnett Practical Rail Engineering'},
['CITEREFBonporti1712'] = {'Bach\'s compositions (sources)'},
['CITEREFBooth2000'] = {'Shakespeare sonnets bibliography'},
['CITEREFBorsari1964'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFBossert1914'] = {'Schaff-Herzog'},
['CITEREFBosworth1968'] = template_names['Cam_Hist_Iran'],
['CITEREFBosworth1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBosworth1983'] = template_names['Iranica'],
['CITEREFBosworth1984'] = template_names['Iranica'],
['CITEREFBosworth1987'] = template_names['Iranica'],
['CITEREFBosworth1988'] = template_names['Iranica'],
['CITEREFBosworth1989'] = template_names['Iranica'],
['CITEREFBosworth1994'] = template_names['Iranica'],
['CITEREFBosworth1995'] = template_names['Iranica'],
['CITEREFBosworth1997'] = template_names['Iranica'],
['CITEREFBosworth1998'] = template_names['Iranica'],
['CITEREFBosworth2000'] = template_names['Iranica'],
['CITEREFBosworth2001'] = template_names['Iranica'],
['CITEREFBosworth2002'] = template_names['Iranica'],
['CITEREFBosworth2003'] = template_names['Iranica'],
['CITEREFBosworth2008'] = template_names['Iranica'],
['CITEREFBosworth2009'] = template_names['Iranica'],
['CITEREFBosworth2010'] = template_names['Iranica'],
['CITEREFBosworth2011'] = template_names['Iranica'],
['CITEREFBosworthCrane1984'] = template_names['Iranica'],
['CITEREFBottoMitchell2002'] = {'Cite ATT Broadway', 'Cite At This Theatre Broadway', 'Cite Broadway At This Theatre', 'Cite Broadway ATT'},
['CITEREFBourbaki1987'] = {'Bourbaki Topological Vector Spaces'},
['CITEREFBourbaki1989'] = {'Bourbaki General Topology Part I Chapters 1-4', 'Bourbaki General Topology Part II Chapters 5-10', 'Bourbaki Algebra I Chapters 1-3 Springer'},
['CITEREFBourbaki1994'] = {'Bourbaki EHM'},
['CITEREFBowen1928'] = {'The Life and Times of Ali ibn Isa'},
['CITEREFBowmanCameronGarnsey2005'] = {'Cambridge Ancient History'},
['CITEREFBoyce1983'] = template_names['Iranica'],
['CITEREFBoyce1986'] = template_names['Iranica'],
['CITEREFBoyce1989'] = template_names['Iranica'],
['CITEREFBoyce2000'] = template_names['Iranica'],
['CITEREFBoyce2009'] = template_names['Iranica'],
['CITEREFBoyd1970'] = {'Boyd-MidWales'},
['CITEREFBoyd1975'] = {'Boyd-FR1'},
['CITEREFBoyd1985'] = {'Boyd-NCaerns2Penrhyn'},
['CITEREFBoyd1986'] = {'Boyd-NCaerns3Dinorwic'},
['CITEREFBoyd1988'] = {'Boyd-SCaerns1'},
['CITEREFBoyd1989'] = {'Boyd-SCaerns2'},
['CITEREFBoyd1990'] = {'Boyd-NCaerns1'},
['CITEREFBradshaw1968'] = {'Bradshaw-1910April'},
['CITEREFBradshaw1985'] = {'Bradshaw-1922July'},
['CITEREFBradshaw2011'] = {'Bradshaw-1895December'},
['CITEREFBradshaw2012'] = {'Bradshaw-1850March'},
['CITEREFBrand1968'] = {'Byzantium Confronts the West'},
['CITEREFBrand1991'] = {'DBI', 'ODB', 'Oxford Dictionary of Byzantium'},
['CITEREFBray2010'] = {'Bray-SDJR'},
['CITEREFBrett2010'] = {'New Cambridge History of Islam'},
['CITEREFBriant1985'] = template_names['Iranica'],
['CITEREFBrosius2000'] = template_names['Iranica'],
['CITEREFBrown2000'] = template_names['Iranica'],
['CITEREFBrown2008'] = {'The Cambridge History of the Byzantine Empire'},
['CITEREFBrunner1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBrunner1983'] = template_names['Cam_Hist_Iran'],
['CITEREFBrunner1984'] = template_names['Iranica'],
['CITEREFBrunner1986'] = template_names['Iranica'],
['CITEREFBryan1886'] = {'Bryan (3rd edition)'},
['CITEREFBryan1889'] = {'Bryan (3rd edition)'},
['CITEREFBuhle1909'] = {'Bach\'s compositions (sources)'},
['CITEREFBulliet1984'] = template_names['Iranica'],
['CITEREFBulookbashiNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFBunbury1857'] = {'DGRG'},
['CITEREFBurant1987'] = {'Cite DCB'},
['CITEREFBurch1911'] = {'Burch Electric Traction'},
['CITEREFBurke1866'] = {'O\'Donnell family tree'},
['CITEREFBurn1985'] = template_names['Cam_Hist_Iran'],
['CITEREFBurrowsWallace1999'] = {'Cite gotham'},
['CITEREFBury1911'] = {'The Imperial Administrative System of the Ninth Century'},
['CITEREFBusse1975'] = template_names['Cam_Hist_Iran'],
['CITEREFBusse1982'] = template_names['Iranica'],
['CITEREFButcherNicholson2018'] = template_names['ODLA'],
['CITEREFButt1995'] = template_names['Butt_Stations'],
['CITEREFBöwering1995'] = template_names['Iranica'],
['CITEREFBürgelMottahedeh1988'] = template_names['Iranica'],
----------< C >----------
['CITEREFCIC1983'] = {'CIC1983bib'},
['CITEREFCalifornia1988'] = {'CA-Rail Passenger Development Plan-1988'},
['CITEREFCalmard1988'] = template_names['Iranica'],
['CITEREFCalmard1999'] = template_names['Iranica'],
['CITEREFCaltrans1984'] = {'Countrystudy'},
['CITEREFCameronWard-PerkinsWhitby2000'] = {'Cambridge Ancient History'},
['CITEREFCanepa2018'] = template_names['ODLA'],
['CITEREFCanny2008'] = {'O\'Donnell family tree'},
['CITEREFCappelCutlerKazhdan1991'] = template_names['ODB'],
['CITEREFCarl_von_Prantl1879'] = {'Cite ADB'},
['CITEREFCarlson2010'] = {'Dlmf'},
['CITEREFCaro1974'] = {'Cite Power Broker'},
['CITEREFCarpenter1977'] = template_names['ME-ref'],
['CITEREFCarpenter1981'] = template_names['ME-ref'],
['CITEREFCarra_de_VauxHodgson1965'] = {'EI2'},
['CITEREFCarter2006'] = {'Carter-RailwaysMotivePowerArgentina'},
['CITEREFCasserley1968'] = {'Casserley-joint'},
['CITEREFCasserleyJohnston1966'] = {'Casserley-LocoGrouping3'},
['CITEREFCasserleyJohnston1974'] = {'Casserley-LocoGrouping3', 'Casserley-LocoGrouping2', '0-7110-0554-0'},
['CITEREFCasway1984'] = {'O\'Donnell family tree'},
['CITEREFCavanna_Ciappina2001'] = {'DBI'},
['CITEREFCawley2001'] = {'Medieval Lands by Charles Cawley', 'MLCC'},
['CITEREFCawley2001'] = {'Medieval Lands by Charles Cawley'},
['CITEREFCawley2010'] = {'MLCC'},
['CITEREFCawley2011'] = {'MLCC'},
['CITEREFChaléardChanson-JabeurBéranger2006'] = {'Chaléard-Le cdf en Afrique'},
['CITEREFChambers1728'] = {'Cyclopaedia 1728'},
['CITEREFChasiotis1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFChaumont1985'] = template_names['Iranica'],
['CITEREFChaumont1986'] = template_names['Iranica'],
['CITEREFChaumont1987'] = template_names['Iranica'],
['CITEREFChaumont1990'] = template_names['Iranica'],
['CITEREFChaumontSchippmann1988'] = template_names['Iranica'],
['CITEREFCheyneBlack1899'] = {'Biblica', 'Cite Biblica'},
['CITEREFCheyneBlack1899–1903'] = {'Cite Biblica'},
['CITEREFCheyneBlack1901'] = {'Cite Biblica'},
['CITEREFCheyneBlack1902'] = {'Cite Biblica'},
['CITEREFCheyneBlack1903'] = {'Cite Biblica'},
['CITEREFChisholm1922'] = {'EB1922', 'Cite EB1922'},
['CITEREFChittick1997'] = template_names['Iranica'],
['CITEREFChkeidze2001'] = template_names['Iranica'],
['CITEREFChoniates1984'] = {'O City of Byzantium'},
['CITEREFChrista_Jost1999'] = template_names['NDB'],
['CITEREFChung1994'] = {'Country study'},
['CITEREFChurchmanHurst2001'] = {'Churchman & Hurst Railways of New Zealand'},
['CITEREFChurchman_&_Hurst2001'] = {'Churchman & Hurst Railways of New Zealand'},
['CITEREFChurella2013'] = {'Churella-PRR-1'},
['CITEREFClementsMcMahon2008'] = {'ClementsMcMahon-GSR Locomotives'},
['CITEREFClinker1978'] = {'Clinker-Stations'},
['CITEREFClinker1988'] = {'Clinker-Stations'},
['CITEREFCoates1990'] = {'Coates-Reading'},
['CITEREFColbyWilliams1916'] = {'New International Encyclopedia', 'NIE'},
['CITEREFColledgeWarlow2006'] = {'Colledge', 'Cite Colledge2006'},
['CITEREFColledgeWarlow2010'] = {'Cite Colledge2010'},
['CITEREFCollins2016'] = {'Cite Collins 2016'},
['CITEREFConolly1998'] = {'IanAllan-PreGroup-Atlas1998'},
['CITEREFConway1990'] = {'Conway A Course in Functional Analysis'},
['CITEREFCosentino2008'] = {'DBI'},
['CITEREFCoulthard-Clark2002'] = {'Australian Dictionary of Biography'},
['CITEREFCousin1910'] = {'A Short Biographical Dictionary of English Literature', 'Cite SBDEL'},
['CITEREFCox1967'] = {'Cox-Upper Darby'},
['CITEREFCox2011'] = {'Cox-Dixie'},
['CITEREFCrevier1993'] = {'Crevier 1993'},
['CITEREFCrockett2007'] = {'Australian Dictionary of Biography'},
['CITEREFCroke2018'] = template_names['ODLA'],
['CITEREFCrone1980'] = {'Slaves on Horses'},
['CITEREFCronin2011'] = template_names['Iranica'],
['CITEREFCroughtonKidnerYoung1982'] = {'Croughton-PrivateStations'},
['CITEREFCruickshanks1970'] = {'HistoryofParliament'},
['CITEREFCudahy2002'] = {'Cudahy-Hudson'},
['CITEREFCudahy2003'] = {'Cudahy-Subways'},
['CITEREFCurta2006'] = {'Southeastern Europe in the Middle Ages, 500–1250'},
----------< D >----------
['CITEREFDBI'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFDZS2015'] = {'Croatia Yearbook 2015'},
['CITEREFDadelsen1957'] = {'Bach\'s compositions (sources)'},
['CITEREFDaftary1990'] = {'Daftary-The Ismailis'},
['CITEREFDaftary2003'] = template_names['Iranica'],
['CITEREFDaftary2007'] = {'Daftary-The Ismailis'},
['CITEREFDaftary2015'] = template_names['Iranica'],
['CITEREFDaiber1988'] = template_names['Iranica'],
['CITEREFDandamayevShahbaziLecoq1986'] = template_names['Iranica'],
['CITEREFDaniel2000'] = template_names['Iranica'],
['CITEREFDaniel2010'] = {'New Cambridge History of Islam'},
['CITEREFDanielsDench1963'] = {'Daniels-NoMore'},
['CITEREFDanielsDench1973'] = {'Daniels-NoMore'},
['CITEREFDanner1975'] = template_names['Cam_Hist_Iran'],
['CITEREFDarleyCanepa2018'] = {'Oxford Dictionary of Late Antiquity'},
['CITEREFDaryaee2009'] = template_names['Iranica'],
['CITEREFDaryaee2018'] = template_names['ODLA'],
['CITEREFDaryaeeCanepa2018'] = template_names['ODLA'],
['CITEREFDavid1961'] = {'Bach\'s compositions (sources)'},
['CITEREFDavidson2010'] = {'HistoryofParliament'},
['CITEREFDavidsonThrush2010'] = {'HistoryofParliament'},
['CITEREFDavies1996'] = {'Davies-PLMLocoList'},
['CITEREFDavies1997'] = {'Davies-NordLocoList'},
['CITEREFDavies2001'] = {'Davies-EstLocoList3', 'Davies-ÉtatLocoList'},
['CITEREFDavies2003'] = {'Davies-SNCFLocoList'},
['CITEREFDaviesFirthLuckingThomas1966'] = {'RCTS-LocosGWR-10'},
['CITEREFDavud2018'] = {'Encyclopaedia Islamica'},
['CITEREFDavudNazerian2008'] = {'Encyclopaedia Islamica'},
['CITEREFDe_Negri1997'] = {'DBI'},
['CITEREFDemircan2010'] = {'TDV Encyclopedia of Islam'},
['CITEREFDeutsch1951'] = {'Schubert\'s compositions (references)'},
['CITEREFDeutsch1978'] = {'Schubert\'s compositions (references)'},
['CITEREFDeutsche_Autos,_Band_2,2001'] = {'Deutsche Autos-2'},
['CITEREFDeutsche_Autos,_Band_3,2001'] = {'Deutsche Autos-3'},
['CITEREFDeutsche_Autos,_Band_4,2001'] = {'Deutsche Autos-4'},
['CITEREFDeutsche_Autos,_Band_5,2001'] = {'Deutsche Autos-5'},
['CITEREFDeutsche_Autos,_Band_6,2001'] = {'Deutsche Autos-6'},
['CITEREFDewick2005'] = {'Dewick-Atlas'},
['CITEREFDiamonstein-Spielvogel2011'] = {'Cite landmarks'},
['CITEREFDickens2018'] = template_names['ODLA'],
['CITEREFDirksen1998'] = {'Bach\'s compositions (sources)'},
['CITEREFDirksen2010'] = {'Bach\'s compositions (sources)'},
['CITEREFDirksen2016'] = {'Bach\'s compositions (sources)'},
['CITEREFDixmier1984'] = {'Dixmier General Topology'},
['CITEREFDoerfer1989'] = template_names['Iranica'],
['CITEREFDoganis1930'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFDoleckiMynard2016'] = {'Dolecki Mynard Convergence Foundations Of Topology'},
['CITEREFDolkart1998'] = {'Cite morningside'},
['CITEREFDonner1995'] = template_names['Iranica'],
['CITEREFDonohue2003'] = {'The Buwayhid Dynasty in Iraq'},
['CITEREFDorin1972'] = {'Dorin-North Western'},
['CITEREFDow1962'] = {'Dow-GC2'},
['CITEREFDow1965'] = {'Dow-GC3'},
['CITEREFDow1985'] = {'Dow-GC1'},
['CITEREFDowney2007'] = {'Downey-Chicago'},
['CITEREFDrechsler2005'] = template_names['Iranica'],
['CITEREFDrummond1964'] = {'HistoryofParliament'},
['CITEREFDrury1985'] = {'Drury Historical Guide 1985'},
['CITEREFDrury1993'] = {'Drury-North American Steam'},
['CITEREFDuchesne-Guillemin1994'] = template_names['Iranica'],
['CITEREFDugundji1966'] = {'Dugundji Topology'},
['CITEREFDuke1995'] = {'Duke-Santa Fe-1'},
['CITEREFDukeKeilty1990'] = {'Duke-RDC'},
['CITEREFDumbarton_Oaks_Hagiography_Database'] = {'Dumbarton Oaks Hagiography Database'},
['CITEREFDunbar1969'] = {'Dunbar-Railroads'},
['CITEREFDuncan-Jones2010'] = {'Shakespeare sonnets bibliography'},
['CITEREFDunlop1895'] = {'O\'Donnell family tree'},
['CITEREFDunlop1985'] = template_names['Iranica'],
['CITEREFDunn2013'] = {'Dunn-Comeng-5'},
['CITEREFDurand-Guédy2008'] = template_names['Iranica'],
['CITEREFDurand-Guédy2010'] = template_names['Iranica'],
['CITEREFDurand-Guédy2013'] = {'Encyclopaedia Islamica'},
['CITEREFDurham1998'] = {'California\'s Geographic Names'},
['CITEREFDurrant1972'] = {'Durrant-Steam Locos Eastern Europe'},
['CITEREFDurrant1981'] = {'Durrant-Garratt-Rev'},
['CITEREFDurrantLewisJorgensen1981'] = {'Durrant-SteamAfrica'},
['CITEREFDömlingKohlhase1971'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1952'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1954'] = {'Bach\'s compositions (sources)'},
['CITEREFDürr1987'] = {'Bach\'s compositions (sources)'},
['CITEREFDürrJones2006'] = {'Bach\'s compositions (sources)'},
['CITEREFDürrKobayashi1998'] = {'Bach\'s compositions (sources)'},
['CITEREFde_Blois2000'] = template_names['Iranica'],
['CITEREFde_Planhol1987'] = template_names['Iranica'],
['CITEREFde_Planhol1988'] = template_names['Iranica'],
----------< E >----------
['CITEREFEIr.1994'] = template_names['Iranica'],
['CITEREFEarle2018'] = {'Gymnosperm Database'},
['CITEREFEbata2019'] = {'BDh'},
['CITEREFEbata2020'] = {'BDh'},
['CITEREFEbrahimKhodaverdian2018'] = {'Encyclopaedia Islamica'},
['CITEREFEdwards1995'] = {'Edwards Functional Analysis Theory and Applications'},
['CITEREFEichberg1976'] = {'Bach\'s compositions (sources)'},
['CITEREFEilers1983'] = template_names ['Cam_Hist_Iran'],
['CITEREFEkbal1991'] = template_names['Iranica'],
['CITEREFEl-Hibri2010'] = {'New Cambridge History of Islam'},
['CITEREFEldredgeHorenstein2014'] = {'Cite concrete'},
['CITEREFElsholz1982'] = {'Schubert\'s compositions (references)'},
['CITEREFElwell-Sutton1984'] = template_names['Iranica'],
['CITEREFEppstein1966'] = {'Bach\'s compositions (sources)'},
['CITEREFEppstein1982'] = {'Bach\'s compositions (sources)'},
['CITEREFEquasis'] = {'Csr', 'Cite ship register'},
['CITEREFEuDaly2009'] = {'Complete Book of North American Railroading'},
['CITEREFEuDalySchaferJessupBoyd2009'] = {'Complete Book of North American Railroading'},
----------< F >----------
['CITEREFFacella2021'] = template_names['Iranica'],
['CITEREFFang1943'] = {'Cite ECCP'},
['CITEREFFarinella2001'] = {'DBI'},
['CITEREFFatehi-NezhadAzarnooshNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFFatehi-nezhadRahimi2008'] = {'Encyclopaedia Islamica'},
['CITEREFFeder1958'] = {'Bach\'s compositions (sources)'},
['CITEREFFederal_Writers'_Project1939'] = {'Cite fednyc'},
['CITEREFFelixMadelung1995'] = template_names['Iranica'],
['CITEREFFernandez1983'] = {'Fernandez1983'},
['CITEREFFesharaki2015'] = {'Encyclopaedia Islamica'},
['CITEREFFiaccadori1991'] = template_names['ODB'],
['CITEREFFikratUmar2008'] = template_names['Iranica'],
['CITEREFFine1991'] = {'The Early Medieval Balkans'},
['CITEREFFine1994'] = {'The Late Medieval Balkans'},
['CITEREFFletcher,_Great_Tank_Scandal'] = {'Book-Fletcher-Great Tank Scandal'},
['CITEREFFletcher,_Universal_Tank'] = {'Book-Fletcher-Universal Tank'},
['CITEREFFloor1992'] = template_names['Iranica'],
['CITEREFFloor2005'] = template_names['Iranica'],
['CITEREFFlora_of_North_America'] = {'EFloras'},
['CITEREFFlora_of_North_America2009'] = {'EFloras'},
['CITEREFFluckMarshallWilson1996'] = {'FluMarWil-LocRailCR'},
['CITEREFFonstad1991'] = template_names['ME-ref'],
['CITEREFForkelTerry1920'] = {'Bach\'s compositions (sources)'},
['CITEREFFornaçon,_Siegfried1957'] = template_names['NDB'],
['CITEREFForrestal1999'] = {'Forrestal-Wineries'},
['CITEREFForster1990'] = {'Cite DCB'},
['CITEREFFoss1991'] = template_names['ODB'],
['CITEREFFoster1971'] = template_names['ME-ref'],
['CITEREFFoster1996'] = {'Foster-Field Guide'},
['CITEREFFrailey2010'] = {'Frailey-Twilight'},
['CITEREFFranke1994'] = {'Cite Cambridge History of China'},
['CITEREFFranz_Schnorr_von_Carolsfeld1883'] = {'Cite ADB'},
['CITEREFFriedrich_Wilhelm_Bautz1975'] = {'BBKL'},
['CITEREFFriedrich_Wilhelm_Bautz1990'] = {'BBKL'},
['CITEREFFry1964'] = {'RCTS-LocosLNER-7'},
['CITEREFFry1966'] = {'RCTS-LocosLNER-5'},
['CITEREFFrye1975'] = template_names['Cam_Hist_Iran'],
['CITEREFFrye1983'] = template_names['Cam_Hist_Iran'],
['CITEREFFrye2004'] = template_names['Iranica'],
['CITEREFFubini2012'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFFudenbergTirole1991'] = {'Cite Fudenberg Tirole 1991'},
['CITEREFFultonHarris1991'] = {'Fulton-Harris'},
----------< G >----------
['CITEREFGarakaniBrown2013'] = {'Encyclopaedia Islamica'},
['CITEREFGardner2005'] = {'MSW3 Microbiotheria'},
['CITEREFGardoni2015'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGareyJohnson1979'] = {'Garey-Johnson'},
['CITEREFGarsoian2000'] = template_names['Iranica'],
['CITEREFGarsoian2004'] = template_names['Iranica'],
['CITEREFGarsoian2005'] = template_names['Iranica'],
['CITEREFGarth2003'] = template_names['ME-ref'],
['CITEREFGazette34205'] = {'London Gazette'},
['CITEREFGazette34339'] = {'London Gazette'},
['CITEREFGazette34390'] = {'London Gazette'},
['CITEREFGazette34427'] = {'London Gazette'},
['CITEREFGazette34558'] = {'London Gazette'},
['CITEREFGazette34870'] = {'London Gazette'},
['CITEREFGazette34978'] = {'London Gazette'},
['CITEREFGazette34989'] = {'London Gazette'},
['CITEREFGazette35037'] = {'London Gazette'},
['CITEREFGazette35107'] = {'London Gazette'},
['CITEREFGazette35134'] = {'London Gazette'},
['CITEREFGazette35284'] = {'London Gazette'},
['CITEREFGazette37560'] = {'London Gazette'},
['CITEREFGazette37590'] = {'London Gazette'},
['CITEREFGazette37598'] = {'London Gazette'},
['CITEREFGazette37610'] = {'London Gazette'},
['CITEREFGazette38020'] = {'London Gazette'},
['CITEREFGazette38611'] = {'London Gazette'},
['CITEREFGeanakoplos1959'] = {'Emperor Michael Palaeologus and the West'},
['CITEREFGeorg_von_Dadelsen1953'] = template_names['NDB'],
['CITEREFGhanoonparvar1989'] = template_names['Iranica'],
['CITEREFGhereghlou2009'] = template_names['Iranica'],
['CITEREFGhereghlou2016'] = template_names['Iranica'],
['CITEREFGhulamiyan2015'] = template_names['Iranica'],
['CITEREFGhulamiyan2015'] = {'Encyclopaedia Islamica'},
['CITEREFGiannasi1975'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGibb1923'] = {'The Arab Conquests in Central Asia'},
['CITEREFGignoux1983'] = template_names['Iranica'],
['CITEREFGignoux1994'] = template_names['Iranica'],
['CITEREFGil1997'] = {'A History of Palestine, 634-1099', 'A History of Palestine, 634–1099'},
['CITEREFGillham2001'] = {'Gillham-Waterloo-City'},
['CITEREFGilliland1969'] = {'Gilliland'},
['CITEREFGilliland1994'] = {'Pop Chronicles 40s'},
['CITEREFGilliverMarshallWeiner2006'] = template_names['ME-ref'],
['CITEREFGilmanPeckColby1905'] = {'Cite NIE', 'New International Encyclopedia', 'NIE'},
['CITEREFGilmanPeckColby1916'] = {'New International Encyclopedia', 'NIE'},
['CITEREFGiunashvili2016'] = template_names['Iranica'],
['CITEREFGleaves1921'] = {'Gleaves'},
['CITEREFGlischinski1997'] = {'Glischinski-Santa Fe'},
['CITEREFGlöckner1983'] = {'Bach\'s compositions (sources)'},
['CITEREFGoldberg1981'] = {'Goldberg-Amtrak'},
['CITEREFGordon2001'] = {'Gordon-The Breaking of a Thousand Swords'},
['CITEREFGraham1974'] = {'Cite DCB'},
['CITEREFGrant1994'] = {'Grant-Death'},
['CITEREFGrant2010'] = {'Grant-Twilight'},
['CITEREFGrant2017'] = {'Grant-RailCo'},
['CITEREFGrassi2018'] = template_names['Iranica'],
['CITEREFGray1986'] = template_names['Cam_Hist_Iran'],
['CITEREFGreenlaw2007'] = {'Greenlaw-Via Rail'},
['CITEREFGregory1991'] = template_names['ODB'],
['CITEREFGregoryŠevčenko1991'] = template_names['ODB'],
['CITEREFGrete_Schemann1957'] = template_names['NDB'],
['CITEREFGrey2002'] = {'Australian Dictionary of Biography'},
['CITEREFGrierson1903'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1908'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1919'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGrierson1967'] = {'Cite LSI', 'LSI', 'Linguistic Survey of India'},
['CITEREFGriffith1991'] = template_names['ODB'],
['CITEREFGriffithsSmith1999'] = {'Griffiths-Sheds1'},
['CITEREFGriffithsSmith2000'] = {'Griffiths-Sheds2'},
['CITEREFGrothendieck1955'] = {'Grothendieck Produits Tensoriels Topologiques et Espaces Nucléaires'},
['CITEREFGrothendieck1973'] = {'Grothendieck Topological Vector Spaces'},
['CITEREFGrothendieckDieudonné1960'] = {'EGA'},
['CITEREFGrothendieckDieudonné1961'] = {'EGA'},
['CITEREFGrothendieckDieudonné1963'] = {'EGA'},
['CITEREFGrothendieckDieudonné1964'] = {'EGA'},
['CITEREFGrothendieckDieudonné1965'] = {'EGA'},
['CITEREFGrothendieckDieudonné1966'] = {'EGA'},
['CITEREFGrothendieckDieudonné1967'] = {'EGA'},
['CITEREFGrothendieckDieudonné1971'] = {'EGA'},
['CITEREFGroves2005'] = {'MSW3 Primates', 'MSW3 Groves'},
['CITEREFGrubb2005'] = {'MSW3 Artiodactyla'},
['CITEREFGuilland1967'] = {'Recherches sur les institutions byzantines'},
['CITEREFGulino2005'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFGunzburg1984'] = {'Gunzburg-History WAGR Steam'},
['CITEREFGurneyNabavi1993'] = template_names['Iranica'],
['CITEREFGutas1987'] = template_names['Iranica'],
['CITEREFGvakharia2001'] = template_names['Iranica'],
['CITEREFGüner1997'] = {'TDV Encyclopedia of Islam'},
----------< H >----------
['CITEREFHaarer2018'] = template_names['ODLA'],
['CITEREFHabibi2021'] = template_names['Iranica'],
['CITEREFHadidi2000'] = template_names['Iranica'],
['CITEREFHaji2008'] = template_names['Iranica'],
['CITEREFHaldon1999'] = {'Warfare, State and Society in the Byzantine World, 565–1204'},
['CITEREFHalliday1985'] = {'Halliday-AustWineCompend'},
['CITEREFHalliday2008'] = {'Halliday-JHWAtlasAust2008'},
['CITEREFHalliday2009'] = {'Halliday-AustWineEncyc'},
['CITEREFHalm1998'] = template_names['Iranica'],
['CITEREFHalpenny1990'] = {'Canadabio'},
['CITEREFHambly1990'] = template_names['Cam_Hist_Iran'],
['CITEREFHambly1991'] = template_names['Cam_Hist_Iran'],
['CITEREFHammondAnderson1993'] = template_names['ME-ref'],
['CITEREFHammondScull1995'] = template_names['ME-ref'],
['CITEREFHammondScull2005'] = template_names['ME-ref'],
['CITEREFHammondScull2006a'] = template_names['ME-ref'],
['CITEREFHammondScull2006b'] = template_names['ME-ref'],
['CITEREFHanaway1988'] = template_names['Iranica'],
['CITEREFHanaway1989'] = template_names['Iranica'],
['CITEREFHanawayLewisohn2004'] = template_names['Iranica'],
['CITEREFHans_Heinrich_Borcherdt1955'] = template_names['NDB'],
['CITEREFHans_Knudsen1972'] = template_names['NDB'],
['CITEREFHansen1988'] = {'Book-Hansen-US Nuclear Weapons'},
['CITEREFHansman1991'] = template_names['Iranica'],
['CITEREFHartshorne1977'] = {'Hartshorne AG'},
['CITEREFHassanpour1989'] = template_names['Iranica'],
['CITEREFHassanpour1995'] = template_names['Iranica'],
['CITEREFHasumi2003'] = {'Hasumi-shiguehiko-ozu-2003'},
['CITEREFHaswell-Smith2004'] = {'Haswell-Smith'},
['CITEREFHaugic1908'] = {'Schaff-Herzog'},
['CITEREFHawting1987'] = {'The First Dynasty of Islam'},
['CITEREFHawting2000'] = {'The First Dynasty of Islam'},
['CITEREFHaynes2011'] = {'RubberBible92nd'},
['CITEREFHeinichen1728'] = {'Bach\'s compositions (sources)'},
['CITEREFHeinrich_Welti1890'] = {'Cite ADB'},
['CITEREFHelgen2005'] = {'MSW3 Scandentia'},
['CITEREFHellmann1965'] = {'Bach\'s compositions (sources)'},
['CITEREFHenrici1725'] = {'Bach\'s compositions (sources)'},
['CITEREFHenryOrsmond1928'] = {'Raiatea family tree'},
['CITEREFHermann_Palm1876'] = {'Cite ADB'},
['CITEREFHerr2000'] = {'Herr-LN'},
['CITEREFHeschel2007'] = {'Encyclopaedia Judaica', 'Cite EJ', 'Cite Encyclopaedia Judaica'},
['CITEREFHewsen1988'] = template_names['Iranica'],
['CITEREFHidyHidyScottHofsummer2004'] = {'Hidy-Great Northern'},
['CITEREFHildHellenkemper1990'] = {'Tabula Imperii Byzantini'},
['CITEREFHildHellenkemper1994'] = {'Tabula Imperii Byzantini'},
['CITEREFHildRestle1981'] = {'Tabula Imperii Byzantini'},
['CITEREFHillenbrand1986'] = template_names['Iranica'],
['CITEREFHills,_Power_from_Steam'] = {'Book-Hills-Power from Steam'},
['CITEREFHills1989'] = {'Book-Hills-Power from Steam'},
['CITEREFHilmarJestremski2004'] = {'Schubert\'s compositions (references)'},
['CITEREFHilton1980'] = {'Hilton-Amtrak'},
['CITEREFHilton1990'] = {'Hilton Narrow Gauge'},
['CITEREFHiltonDue1960'] = {'Hilton-Interurban'},
['CITEREFHinton1986'] = {'HistoryofParliament'},
['CITEREFHirsch1906'] = {'Cite JE1906'},
['CITEREFHistoric_Environment_Scotland'] = {'Canmore'},
['CITEREFHistoric_Environment_Scotland1972'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland1976'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland2020'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_Scotland:_Rusco_Tower2020'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_ScotlandLB33744'] = {'Historic Environment Scotland'},
['CITEREFHistoric_Environment_ScotlandLB50114'] = {'Historic Environment Scotland'},
['CITEREFHob.'] = {'Schubert\'s compositions (references)'},
['CITEREFHoffmanSmith2005'] = {'MSW3 Lagomorpha'},
['CITEREFHoffmann1738'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1983'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1987'] = {'Bach\'s compositions (sources)'},
['CITEREFHofmann1999'] = {'Bach\'s compositions (sources)'},
['CITEREFHolland1972'] = {'Holland-Vol 2'},
['CITEREFHolland1988'] = {'Cite DCB'},
['CITEREFHolland2001'] = {'Holland-Classic'},
['CITEREFHollingsworth1980'] = {'Hollingsworth-Atlas-Rigby'},
['CITEREFHollingsworth1991'] = template_names['ODB'],
['CITEREFHollingsworthCutler1991'] = template_names['ODB'],
['CITEREFHolmgren2003'] = {'EFloras'},
['CITEREFHoltBiddle1986'] = {'Holt-NorthWest'},
['CITEREFHolton1989'] = {'Holton-Reading-1'},
['CITEREFHonigmann1935'] = {'Byzance et les Arabes'},
['CITEREFHopley1983'] = {'Australian Dictionary of Biography'},
['CITEREFHort1911'] = {'DCBL'},
['CITEREFHorváth1966'] = {'Horváth Topological Vector Spaces and Distributions Volume 1 1966'},
['CITEREFHosseini2017'] = template_names['Iranica'],
['CITEREFHounshell1984'] = {'Hounshell1984'},
['CITEREFHudson1997'] = {'Country study'},
['CITEREFHughes1990'] = {'Hughes-IndianLocos1'},
['CITEREFHughes1992'] = {'Hughes-IndianLocos2'},
['CITEREFHughes1994'] = {'Hughes-IndianLocos3'},
['CITEREFHughes1996'] = {'Hughes-IndianLocos4'},
['CITEREFHummel1943'] = {'Cite ECCP'},
['CITEREFHumphreys2018'] = template_names['ODLA'],
['CITEREFHunter-Crawley2018'] = template_names['ODLA'],
['CITEREFHunter2008'] = {'Country study'},
['CITEREFHutter2009'] = template_names['Iranica'],
['CITEREFHutterer2005'] = {'MSW3 Soricomorpha'},
['CITEREFHütter2012'] = {'Hütter-50bis53'},
['CITEREFHütter2015'] = {'Hütter-54bis59'},
['CITEREFHütter2021'] = {'Hütter-60bis91'},
----------< I >----------
['CITEREFIbn_Khallikan1843'] = {'Ibn Khallikan\'s Biographical Dictionary'},
['CITEREFImber2002'] = {'Imber-The Ottoman Empire, 1300–1650'},
['CITEREFInalcik1989'] = {'Setton-A History of the Crusades'},
['CITEREFIranica:_Bahrām'] = template_names['Iranica'],
['CITEREFIrvine2006'] = template_names['Iranica'],
['CITEREFIshino1998'] = {'Teishajo'},
['CITEREFIshkevariNejad2008'] = {'Encyclopaedia Islamica'},
['CITEREFIvey1919'] = {'Ivey-Marquette'},
----------< J >----------
['CITEREFJackson1908'] = {'Schaff-Herzog'},
['CITEREFJackson1988'] = template_names['Iranica'],
['CITEREFJackson1989'] = template_names['Iranica'],
['CITEREFJackson1995'] = {'Cite enc-nyc'},
['CITEREFJackson2010'] = {'Cite enc-nyc2'},
['CITEREFJacksonMelville2001'] = template_names['Iranica'],
['CITEREFJacobs1904'] = {'Cite Jewish Encyclopedia'},
['CITEREFJarchow1981'] = {'Jarchow Locally Convex Spaces'},
['CITEREFJavadiBurrill1988'] = template_names['Iranica'],
['CITEREFJohn_O'Donovan1856'] = {'Cite AFM'},
['CITEREFJohnstonWelshSchafer2001'] = {'Johnston-Streamliner'},
['CITEREFJones2011'] = {'Cite EPD'},
['CITEREFJordan2002'] = {'Jordan-WineWABest'},
['CITEREFJoshi1983'] = {'Joshi Introduction to General Topology'},
['CITEREFJoslen2003'] = {'Joslen-OOB'},
['CITEREFJowett1867'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFJowett1989'] = {'Jowett-Atlas', 'Carnarvonshire Railway'},
['CITEREFJowett2000'] = {'Jowett-Nationalised'},
['CITEREFJullien2018'] = template_names['ODLA'],
['CITEREFJupp1986'] = {'HistoryofParliament'},
----------< K >----------
['CITEREFK.'] = {'Schubert\'s compositions (references)'},
['CITEREFKadinsky2016'] = {'Cite Hidden Waters NYC'},
['CITEREFKaegi1991'] = template_names['ODB'],
['CITEREFKamaly2006'] = template_names['Iranica'],
['CITEREFKamp1981'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFKang2008'] = {'Country study'},
['CITEREFKaramatiMelvin-Koushki2021'] = template_names['Iranica'],
['CITEREFKaramatiMelvin-Koushki2021'] = {'Encyclopaedia Islamica'},
['CITEREFKarimi-Hakkak1997'] = template_names['Iranica'],
['CITEREFKarimiMaghsoodi2013'] = {'Encyclopaedia Islamica'},
['CITEREFKarl_Frohnmeyer1953'] = template_names['NDB'],
['CITEREFKarnow1989'] = {'Cite-Karnow'},
['CITEREFKasheff2001'] = template_names['Iranica'],
['CITEREFKayvaniGholami2008'] = {'Encyclopaedia Islamica'},
['CITEREFKazhdan1991'] = template_names['ODB'],
['CITEREFKazhdanCutler1991'] = template_names['ODB'],
['CITEREFKazhdanJeffreys1991'] = template_names['ODB'],
['CITEREFKazhdanŠevčenko1991'] = template_names['ODB'],
['CITEREFKeall1987'] = template_names['Iranica'],
['CITEREFKeefe2006'] = {'Schubert\'s compositions (references)'},
['CITEREFKeller1937'] = {'Bach\'s compositions (sources)'},
['CITEREFKelly1988'] = {'Cite GEIL'},
['CITEREFKellyBurrage1920'] = {'Cite AMB1920'},
['CITEREFKennedy1998'] = {'The Cambridge History of Egypt', 'Cite Kennedy 1998', 'Cambridge History of Egypt'},
['CITEREFKennedy2001'] = {'Kennedy-The Armies of the Caliphs'},
['CITEREFKennedy2004'] = {'The Prophet and the Age of the Caliphates'},
['CITEREFKennedy2007'] = {'Kennedy-The Great Arab Conquests'},
['CITEREFKennedy2016'] = {'The Prophet and the Age of the Caliphates'},
['CITEREFKenyon2011'] = {'Bach\'s compositions (sources)'},
['CITEREFKerrigan1995'] = {'Shakespeare sonnets bibliography'},
['CITEREFKettenhofen1995'] = template_names['Iranica'],
['CITEREFKettenhofen2001'] = template_names['Iranica'],
['CITEREFKettenhofenBournoutianHewsen1998'] = template_names['Iranica'],
['CITEREFKhaleelulla1982'] = {'Khaleelulla Counterexamples in Topological Vector Spaces'},
['CITEREFKhaleghi-Motlagh1999'] = template_names['Iranica'],
['CITEREFKhaleghi-Motlagh2001'] = template_names['Iranica'],
['CITEREFKhan2012'] = {'Cite Banglapedia'},
['CITEREFKhatibiNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFKim1994'] = {'Country study'},
['CITEREFKirnberger1774'] = {'Bach\'s compositions (sources)'},
['CITEREFKirnberger1780'] = {'Bach\'s compositions (sources)'},
['CITEREFKlein2006'] = {'Klein-UP-2'},
['CITEREFKlíma1988'] = template_names['Iranica'],
['CITEREFKobayashi1978'] = {'Bach\'s compositions (sources)'},
['CITEREFKoderHild1976'] = {'Tabula Imperii Byzantini'},
['CITEREFKoderSoustalKoder1998'] = {'Tabula Imperii Byzantini'},
['CITEREFKoeppel2015'] = {'Cite citygrid'},
['CITEREFKofos1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFKohler1902'] = {'Cite Jewish Encyclopedia'},
['CITEREFKolde1914'] = {'Schaff-Herzog'},
['CITEREFKoliopoulos1978'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFKolmogorovFomin1957'] = {'Kolmogorov Fomin Elements of the Theory of Functions and Functional Analysis'},
['CITEREFKonrad_Ameln1985'] = template_names['NDB'],
['CITEREFKoska2011'] = {'Bach\'s compositions (sources)'},
['CITEREFKratville1962'] = {'Kratville-SSL'},
['CITEREFKretzschmar1910'] = {'Bach\'s compositions (sources)'},
['CITEREFKube2009'] = {'Schubert\'s compositions (references)'},
['CITEREFKurz1983'] = template_names['Cam_Hist_Iran'],
['CITEREFKuznik2008'] = {'Bach\'s compositions (sources)'},
['CITEREFKöthe1969'] = {'Köthe Topological Vector Spaces I'},
['CITEREFKöthe1979'] = {'Köthe Topological Vector Spaces II'},
['CITEREFKöthe1983'] = {'Köthe Topological Vector Spaces I'},
['CITEREFKülzer2008'] = {'Tabula Imperii Byzantini'},
['CITEREFKüçükaşcı2001'] = {'TDV Encyclopedia of Islam'},
----------< L >----------
['CITEREFLa_Porta2018'] = template_names['ODLA'],
['CITEREFLacourcière1974'] = {'Cite DCB'},
['CITEREFLadefogedMaddieson1996'] = {'SOWL'},
['CITEREFLandau-Tasseron2010'] = {'New Cambridge History of Islam'},
['CITEREFLandauCondit1996'] = {'Cite nysky'},
['CITEREFLandmann1907'] = {'Bach\'s compositions (sources)'},
['CITEREFLang1983'] = template_names['Cam_Hist_Iran'],
['CITEREFLangaroodiCooper2008'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiCooper2015'] = template_names['Iranica'],
['CITEREFLangaroodiCooper2015'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroodiNegahban2015'] = template_names['Iranica'],
['CITEREFLangaroodiNegahban2015'] = {'Encyclopaedia Islamica'},
['CITEREFLangaroudi2001'] = template_names['Iranica'],
['CITEREFLatham1982–2021'] = template_names['Iranica'],
['CITEREFLazard1975'] = template_names['Cam_Hist_Iran'],
['CITEREFLaërtius1925'] = {'Cite Lives of the Eminent Philosophers', 'Cite LotEP'},
['CITEREFLeCoq1986'] = template_names['Iranica'],
['CITEREFLe_Quien1740'] = {'Oriens Christianus'},
['CITEREFLe_Strange1900'] = {'Baghdad During the Abbasid Caliphate'},
['CITEREFLe_Strange1905'] = {'Lands of the Eastern Caliphate'},
['CITEREFLe_Strange1922'] = {'Baghdad During the Abbasid Caliphate'},
['CITEREFLeblanc1979'] = {'Cite DCB'},
['CITEREFLee1903'] = {'Cite DNBIE'},
['CITEREFLee2018'] = template_names['ODLA'],
['CITEREFLeisingerWollny1993'] = {'Bach\'s compositions (sources)'},
['CITEREFLerner1988'] = template_names['Iranica'],
['CITEREFLev1999'] = {'Saladin in Egypt'},
['CITEREFLevitan2001'] = {'Springer'},
['CITEREFLewin1925'] = {'Lewin-EarlyRail'},
['CITEREFLewis1969'] = {'Setton-A History of the Crusades'},
['CITEREFLewis1986'] = {'Lewis-Shortline-1986'},
['CITEREFLewis1991'] = {'Lewis-Shortline-1991'},
['CITEREFLewis1996'] = {'Lewis-Shortline-1996'},
['CITEREFLewis2001'] = template_names['Iranica'],
['CITEREFLiederNet_Archive'] = {'Schubert\'s compositions (references)'},
['CITEREFLieu1997'] = template_names['Iranica'],
['CITEREFLighthouses_of_Australia_Inc'] = {'Cite loa'},
['CITEREFLind1986'] = {'Lind-Limiteds'},
['CITEREFLittle1974'] = {'Cite DCB'},
['CITEREFLongnon1969'] = {'Setton-A History of the Crusades'},
['CITEREFLosensky2003'] = template_names['Iranica'],
['CITEREFLoverance2018'] = template_names['ODLA'],
['CITEREFLukonin1983'] = {'Cambridge History of Iran'},
['CITEREFLurje2010'] = template_names['Iranica'],
['CITEREFLuttrell1975'] = {'Setton-A History of the Crusades'},
['CITEREFLuttrell1987'] = {'DBI'},
['CITEREFLynch2004'] = {'Lynch-Penn Central'},
['CITEREFLynch2005'] = {'Lynch-New Haven passenger'},
['CITEREFLynch2018'] = template_names['ODLA'],
['CITEREFLéger1990'] = {'Cite DCB'},
['CITEREFle_Fleming1953'] = {'RCTS-LocosGWR-8'},
['CITEREFle_Fleming1960'] = {'RCTS-LocosGWR-8'},
----------< M >----------
['CITEREFMacDermot1927'] = {'Infobox GWR'},
['CITEREFMacDermot1931'] = {'Infobox GWR'},
['CITEREFMacEoin1988'] = template_names['Iranica'],
['CITEREFMacKenzie1992'] = template_names['Iranica'],
['CITEREFMadelung1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMadelung1978'] = {'EI2'},
['CITEREFMadelung1983'] = template_names['Iranica'],
['CITEREFMadelung1984'] = template_names['Iranica'],
['CITEREFMadelung1988'] = template_names['Iranica'],
['CITEREFMadelung1993'] = template_names['Iranica'],
['CITEREFMadelung2003'] = template_names['Iranica'],
['CITEREFMadelungFelix1995'] = template_names['Iranica'],
['CITEREFMaeda2009'] = template_names['Iranica'],
['CITEREFMagdalino2002'] = {'The Empire of Manuel I Komnenos'},
['CITEREFMaiken1989'] = {'Maiken-Night Trains'},
['CITEREFMailer2004'] = {'Mailer-Omaha Road'},
['CITEREFMajidiNegahban'] = {'Encyclopaedia Islamica'},
['CITEREFMalandra2009'] = template_names['Iranica'],
['CITEREFManfred_Knedlik2007'] = {'BBKL'},
['CITEREFMarshak1994'] = template_names['Iranica'],
['CITEREFMarshak2002'] = template_names['Iranica'],
['CITEREFMarshall1823'] = {'Cite RNB1823'},
['CITEREFMarshall1824'] = {'Cite RNB1823'},
['CITEREFMarshall1825'] = {'Cite RNB1823'},
['CITEREFMarshall1827'] = {'Cite RNB1823'},
['CITEREFMarshall1828'] = {'Cite RNB1823'},
['CITEREFMarshall1829'] = {'Cite RNB1823'},
['CITEREFMarshall1830'] = {'Cite RNB1823'},
['CITEREFMarshall1831'] = {'Cite RNB1823'},
['CITEREFMarshall1832'] = {'Cite RNB1823'},
['CITEREFMarshall1833'] = {'Cite RNB1823'},
['CITEREFMarshall1835'] = {'Cite RNB1823'},
['CITEREFMarshall1972'] = {'Lancashire & Yorkshire Railway 3'},
['CITEREFMarshall2001'] = {'Marshall-INGSR'},
['CITEREFMartin_Persch1992'] = {'BBKL'},
['CITEREFMartin_Persch1993'] = {'BBKL'},
['CITEREFMartin_Persch1996'] = {'BBKL'},
['CITEREFMartindale1980'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMartindale1992'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMartindaleJonesMorris1971'] = {'Prosopography of the Later Roman Empire', 'PLRE'},
['CITEREFMasoud_Jalali-Moqaddam2015'] = {'Encyclopaedia Islamica'},
['CITEREFMatini1987'] = template_names['Iranica'],
['CITEREFMatthee2008'] = template_names['Iranica'],
['CITEREFMatthee2015'] = template_names['Iranica'],
['CITEREFMaul2005'] = {'Bach\'s compositions (sources)'},
['CITEREFMayGray2006'] = {'MayGray-WAGRPassCar'},
['CITEREFMazzaoui2002'] = template_names['Iranica'],
['CITEREFMcArthurMcArthur2003'] = {'Cite ogn', 'Cite Oregon Geographic Names'},
['CITEREFMcCaffrey1990'] = template_names['Iranica'],
['CITEREFMcCorduck2004'] = {'McCorduck 2004'},
['CITEREFMcCurdyRogers1902'] = {'Cite Jewish Encyclopedia'},
['CITEREFMcDonnell2015'] = {'McDonnell-Locomotives-2nd'},
['CITEREFMcGhee2008'] = {'Cite McGhee 2008'},
['CITEREFMeiningen1704'] = {'Bach\'s compositions (sources)'},
['CITEREFMeints1992'] = {'Meints-Companies'},
['CITEREFMeints2005'] = {'Meints-Lines'},
['CITEREFMelamed1988'] = {'Bach\'s compositions (sources)'},
['CITEREFMelamed1995'] = {'Bach\'s compositions (sources)'},
['CITEREFMelville1997'] = template_names['Iranica'],
['CITEREFMelville2003'] = template_names['Iranica'],
['CITEREFMennell1892'] = {'Dictionary of Australasian Biography'},
['CITEREFMetcalfe2009'] = {'The Muslims of Medieval Italy'},
['CITEREFMiddleton1961'] = {'Middleton-Interurban'},
['CITEREFMiddleton2001'] = {'Middleton-Electrified-2nd'},
['CITEREFMiddleton2002'] = {'Middleton-PRR-Under-Wire'},
['CITEREFMiddletonSmerkDiehl2007'] = {'Encyclopedia of North American Railroads'},
['CITEREFMiles1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMillar2011'] = {'NZR Steam Locomotive'},
['CITEREFMiller'] = {'Encyclopaedia Islamica'},
['CITEREFMiller1908'] = {'The Latins in the Levant', 'Latins in the Levant'},
['CITEREFMiller1921'] = {'Essays on the Latin Orient'},
['CITEREFMinnich2008'] = {'Country study'},
['CITEREFMiramar_Ship_Index'] = {'Csr', 'Cite ship register'},
['CITEREFMitchell1965'] = {'Mitchell TOC'},
['CITEREFMittermeierKonstantHawkinsLouis2006'] = {'LoM2'},
['CITEREFMittermeierLouisRichardsonSchwitzer2010'] = {'LoM3'},
['CITEREFMittermeierTattersallKonstantMeyers1994'] = {'LoM1'},
['CITEREFMoore1875'] = {'Cite CEM'},
['CITEREFMorana1993'] = {'Bach\'s compositions (sources)'},
['CITEREFMorony2009'] = template_names['Iranica'],
['CITEREFMoschonas1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFMottahedeh1975'] = template_names['Cam_Hist_Iran'],
['CITEREFMozartHaydnHaydn2008'] = {'Schubert\'s compositions (references)'},
['CITEREFMunkres1974'] = {'Munkres Topology'},
['CITEREFMunkres2000'] = {'Munkres Topology'},
['CITEREFMurray2006'] = {'Murray-Illinois Central'},
['CITEREFMusserCarleton2005'] = {'MSW3 Muroidea'},
['CITEREFMüller,_Hans-Christian1966'] = template_names['NDB'],
----------< N >----------
['CITEREFNSA_II,_15'] = {'Schubert\'s compositions (references)'},
['CITEREFNSA_scores'] = {'Schubert\'s compositions (references)'},
['CITEREFNSA_website'] = {'Schubert\'s compositions (references)'},
['CITEREFNagel1990'] = template_names['Iranica'],
['CITEREFNariciBeckenstein2011'] = {'Narici Beckenstein Topological Vector Spaces'},
['CITEREFNavāʾī1988'] = template_names['Iranica'],
['CITEREFNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFNersessian2018'] = template_names['ODLA'],
['CITEREFNetzer1998'] = template_names['Iranica'],
['CITEREFNetzer2007'] = template_names['Iranica'],
['CITEREFNeukirch1999'] = {'Neukirch ANT'},
['CITEREFNeukirchSchmidtWingberg2000'] = {'Neukirch et al. CNF'},
['CITEREFNew_York_City_Landmarks_Preservation_CommissionDolkartPostal2009'] = {'Cite nycland'},
['CITEREFNewbould1999'] = {'Schubert\'s compositions (references)'},
['CITEREFNewman1994'] = template_names['Iranica'],
['CITEREFNicholsonCanepaDaryaee2018'] = template_names['ODLA'],
['CITEREFNicol1988'] = {'Byzantium and Venice: A Study in Diplomatic and Cultural Relations'},
['CITEREFNicol1992'] = {'The Immortal Emperor: The Life and Legend of Constantine Palaiologos, Last Emperor of the Romans'},
['CITEREFNicol1993'] = {'The Last Centuries of Byzantium, 1261–1453', 'The Last Centuries of Byzantium'},
['CITEREFNock1974'] = {'Nock-EustonGlasgow'},
----------< O >----------
['CITEREFO'Byrne1849'] = {'Cite NBD1849'},
['CITEREFO'ConnorRobertson1996'] = {'MacTutor Biography', 'MacTutor'},
['CITEREFO'ConnorRobertson2000'] = {'MacTutor Biography', 'MacTutor'},
['CITEREFO'Donoghue1897'] = {'Cite DNB'},
['CITEREFODB'] = template_names['ODB'],
['CITEREFODLA'] = template_names['ODLA'],
['CITEREFOberling1984'] = template_names['Iranica'],
['CITEREFOberling2008'] = template_names['Iranica'],
['CITEREFOberling2010'] = template_names['Iranica'],
['CITEREFOdisheli2018'] = template_names['ODLA'],
['CITEREFOfficial_Guide_of_the_Railways1950'] = {'Official Guide of the Railways'},
['CITEREFOgorek2012'] = {'Ogorek-South Shore'},
['CITEREFOikonomides1991'] = template_names['ODB'],
['CITEREFOikonomou1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFOlbrycht2021'] = template_names['Iranica'],
----------< P >----------
['CITEREFPLP'] = {'Prosopographisches Lexikon der Palaiologenzeit', 'PLP'},
['CITEREFPalmer1875'] = {'Cite ADB'},
['CITEREFPalmerStewart1965'] = {'Palmer & Stewart'},
['CITEREFPanainoAbdollahyBalland1990'] = template_names['Iranica'],
['CITEREFPandariHirtensteinNegahban2013'] = {'Encyclopaedia Islamica'},
['CITEREFParvin2003'] = template_names['Iranica'],
['CITEREFParvin2009'] = template_names['Iranica'],
['CITEREFPatience1996'] = {'Patience-SteamTwilight'},
['CITEREFPatton2005'] = {'MSW3 Geomyidae'},
['CITEREFPaul2000'] = template_names['Iranica'],
['CITEREFPaxtonBourne1985'] = {'Paxton-Bourne'},
['CITEREFPeacock2011'] = template_names['Iranica'],
['CITEREFPeck1898'] = {'HDCA'},
['CITEREFPerlis2001'] = {'Springer'},
['CITEREFPerreault2004'] = {'Bach\'s compositions (sources)'},
['CITEREFPerry1983'] = template_names['Cam_Hist_Iran'],
['CITEREFPerry1990'] = template_names['Cam_Hist_Iran'],
['CITEREFPerry1991'] = template_names['Cam_Hist_Iran'],
['CITEREFPetropoulosKoumarianou1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFPetrucci1982'] = {'DBI'},
['CITEREFPezeshk2017'] = {'Encyclopaedia Islamica'},
['CITEREFPezeshkKhaleeli2017'] = template_names['Iranica'],
['CITEREFPezeshkKhaleeli2017'] = {'Encyclopaedia Islamica'},
['CITEREFPfau2008'] = {'Bach\'s compositions (sources)'},
['CITEREFPinkepank1973'] = {'Pinkepank diesel spotters guide 2'},
['CITEREFPlantlist2016'] = {'Plantlist'},
['CITEREFPlaten1976'] = {'Bach\'s compositions (sources)'},
['CITEREFPloumidisAlexiou1974'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFPmbZ'] = {'Prosopographie der mittelbyzantinischen Zeit', 'PMBZ'},
['CITEREFPolemis1968'] = {'Polemis-The Doukai'},
['CITEREFPope2007'] = {'Encyclopaedia Judaica', 'Cite EJ', 'Cite Encyclopaedia Judaica'},
['CITEREFPopplewell'] = {'Popplewell-Gazetteer'},
['CITEREFPotts2018'] = template_names['ODLA'],
['CITEREFPottsCanepa2018'] = template_names['ODLA'],
['CITEREFPourshariati2017'] = {'Encyclopædia Iranica Online'},
['CITEREFPozza1992'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFPrawer1985'] = {'Setton-A History of the Crusades'},
['CITEREFPritsak1991'] = template_names['ODB'],
['CITEREFProsopographie_der_mittelbyz._Zeit'] = {'Prosopographie der mittelbyzantinischen Zeit'},
----------< Q >----------
['CITEREFQuick2009'] = {'Quick-Stations'},
['CITEREFQuick2019'] = {'Quick-stations-5'},
['CITEREFQuinn2003'] = template_names['Iranica'],
----------< R >----------
['CITEREFRaditsa1983'] = template_names['Cam_Hist_Iran'],
['CITEREFRahman1983'] = template_names['Iranica'],
['CITEREFRaja'i1987'] = template_names['Iranica'],
['CITEREFRamaer1974'] = {'Ramaer-SteamLocosEAR'},
['CITEREFRansome-Wallis1971'] = {'Ransome-Wallis 1'},
['CITEREFRateliff2007'] = template_names['ME-ref'],
['CITEREFRavegnano2000'] = {'DBI'},
['CITEREFReed1953'] = {'RCTS-LocosGWR-2'},
['CITEREFReed1975'] = {'Reed-Streamline era'},
['CITEREFReed1997'] = {'Schubert\'s compositions (references)'},
['CITEREFReinhard_Tenberg1990'] = {'BBKL'},
['CITEREFRettinghaus2020'] = {'BDh'},
['CITEREFReynolds1921'] = {'Cite Collier\'s', 'Collier\'s'},
['CITEREFReynoldsOroszi2000'] = {'Reynolds-BO'},
['CITEREFRezaHirtensteinGholami2021'] = {'Encyclopaedia Islamica'},
['CITEREFRezakhani2018'] = template_names['ODLA'],
['CITEREFRezvani2014'] = template_names['Iranica'],
['CITEREFRichter-Bernburg2003'] = template_names['Iranica'],
['CITEREFRichter2018'] = {'BDh'},
['CITEREFRigo2005'] = template_names['ODB'],
['CITEREFRipleyDana1863'] = {'New American Cyclopedia'},
['CITEREFRipleyDana1864'] = {'New American Cyclopedia'},
['CITEREFRipleyDana1879'] = {'Cite AmCyc'},
['CITEREFRistaino1988'] = {'Country study'},
['CITEREFRobert_Eitner1891'] = {'Cite ADB'},
['CITEREFRobertson1983'] = {'Robertson-OriginScot'},
['CITEREFRoe1916'] = {'Roe1916'},
['CITEREFRoe1937'] = {'Roe1937'},
['CITEREFRoemer1986'] = template_names['Cam_Hist_Iran'],
['CITEREFRoemer1989'] = template_names['Iranica'],
['CITEREFRoemer2004'] = template_names['Iranica'],
['CITEREFRolt1965'] = {'Rolt1965'},
['CITEREFRoltKichenside1982'] = {'Rolt-Red'},
['CITEREFRose1857'] = {'Cite Newgenbio'},
['CITEREFRosenfeld1974'] = template_names['NDB'],
['CITEREFRosenzweigBlackmar1992'] = {'Cite Central Park History', 'Cite Central Park history'},
['CITEREFRowledge1975'] = {'Rowledge-Engines of the LMS'},
['CITEREFRowledge1993'] = {'Rowledge-Irish Steam Register'},
['CITEREFRowlett'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2007'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2012'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2013'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2016'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowlett2017'] = {'Cite rowlett', 'Cite Rowlett'},
['CITEREFRowson1998'] = template_names['Iranica'],
['CITEREFRudin1973'] = {'Rudin Walter Functional Analysis'},
['CITEREFRudin1991'] = {'Rudin Walter Functional Analysis'},
['CITEREFRunciman1951'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1951–1954'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1952'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1954'] = {'Runciman-A History of the Crusades'},
['CITEREFRunciman1989'] = {'Runciman-A History of the Crusades'},
['CITEREFRussell1985'] = {'Setton-A History of the Crusades', 'Encyclopædia Iranica Online', 'Encyclopædia Iranica', 'Encyclopaedia Iranica', 'Cite Encyclopædia Iranica Online'},
['CITEREFRussell1986'] = template_names['Iranica'],
['CITEREFRussell1987'] = template_names['Iranica'],
['CITEREFRussellNorvig2003'] = {'Russell Norvig 2003'},
['CITEREFRybczynski2000'] = {'Rybczynski2000'},
['CITEREFRypka1968'] = template_names['Cam_Hist_Iran'],
----------< S >----------
['CITEREFSR_staff2013'] = {'Houston family tree'},
['CITEREFSadeghiTehrani2008'] = {'Encyclopaedia Islamica'},
['CITEREFSadıkoğlu1996'] = {'TDV Encyclopedia of Islam'},
['CITEREFSafa1987'] = template_names['Iranica'],
['CITEREFSafa1988'] = template_names['Iranica'],
['CITEREFSafa1989'] = template_names['Iranica'],
['CITEREFSafa1994'] = template_names['Iranica'],
['CITEREFSafa2003'] = template_names['Iranica'],
['CITEREFSajjadiAsatryanMelvin-Koushki'] = {'Encyclopaedia Islamica Online'},
['CITEREFSajjadiAsatryanMelvin-Koushki'] = {'Encyclopaedia Islamica'},
['CITEREFSajjadiAsatryanMelvin-Koushki2021'] = template_names['Iranica'],
['CITEREFSalbiev2021'] = template_names['Iranica'],
['CITEREFSalo2004'] = template_names['ME-ref'],
['CITEREFSamiʿiMelvin-Koushki2013'] = {'Encyclopaedia Islamica'},
['CITEREFSanders1998'] = {'The Cambridge History of Egypt', 'Cambridge History of Egypt'},
['CITEREFSanders2003'] = {'Sanders-Indiana'},
['CITEREFSanders2006'] = {'Sanders-Heartland'},
['CITEREFSanders2007'] = {'Sanders-Akron'},
['CITEREFSarikakis1974'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSaunders2001'] = {'Saunders-Merging Lines'},
['CITEREFSaunders2013'] = {'Saunders-Giants of the Seas'},
['CITEREFSavadaShaw1992'] = {'Country study'},
['CITEREFSavoryKaramustafa1998'] = template_names['Iranica'],
['CITEREFScarce1986'] = template_names['Iranica'],
['CITEREFSchaeferWolff1999'] = {'Schaefer Wolff Topological Vector Spaces'},
['CITEREFSchafer1996'] = {'Schafer-Classic-Railroads-1'},
['CITEREFSchafer1998'] = {'Schafer-Vintage Diesel'},
['CITEREFSchafer2000'] = {'Schafer-More-Classic'},
['CITEREFSchafer2003'] = {'Schafer-Classic-Railroads-3'},
['CITEREFSchaferSolomon1997'] = {'Schafer-Pennsylvania'},
['CITEREFSchaferWelsh1997'] = {'Schafer-Classic'},
['CITEREFSchaferWelsh2002'] = {'Schafer-Streamliners'},
['CITEREFSchaferWelshHolland2001'] = {'Schafer-American passenger train'},
['CITEREFSchaff-Herzog'] = {'Schaff-Herzog'},
['CITEREFSchechter1996'] = {'Schechter Handbook of Analysis and Its Foundations'},
['CITEREFScheide1960'] = {'Bach\'s compositions (sources)'},
['CITEREFSchicht1805'] = {'Bach\'s compositions (sources)'},
['CITEREFSchilling1997'] = {'Schilling-pop-culture'},
['CITEREFSchindel2013'] = template_names['Iranica'],
['CITEREFSchippmann1986'] = template_names['Iranica'],
['CITEREFSchippmann1987'] = template_names['Iranica'],
['CITEREFSchlitter2005'] = {'MSW3 Tubulidentata'},
['CITEREFSchlumberger1983'] = template_names['Cam_Hist_Iran'],
['CITEREFSchmieder1950'] = {'Bach\'s compositions (sources)'},
['CITEREFSchmieder1990'] = {'Bach\'s compositions (sources)'},
['CITEREFSchmitt1986'] = template_names['Iranica'],
['CITEREFSchmitt1989'] = template_names['Iranica'],
['CITEREFSchmitt1993'] = template_names['Iranica'],
['CITEREFSchmitt1994'] = template_names['Iranica'],
['CITEREFSchmitt1995'] = template_names['Iranica'],
['CITEREFSchmitt2002'] = template_names['Iranica'],
['CITEREFSchmitt2004'] = template_names['Iranica'],
['CITEREFSchmitt2005'] = template_names['Iranica'],
['CITEREFSchmitt2018'] = template_names['Iranica'],
['CITEREFSchmittBailey1986'] = template_names['Iranica'],
['CITEREFSchmitz1870'] = {'Cite DGRBM'},
['CITEREFSchneider1907'] = {'Bach\'s compositions (sources)'},
['CITEREFSchneider1912'] = {'Bach\'s compositions (sources)'},
['CITEREFScholze1736'] = {'Bach\'s compositions (sources)'},
['CITEREFSchroeter1961'] = {'Schroeter-Eisenbahnen'},
['CITEREFSchroeterRamaer1993'] = {'Schroeter-Ramaer-Eisenbahnen'},
['CITEREFSchubert-online'] = {'Schubert\'s compositions (references)'},
['CITEREFSchubert1968'] = {'Schubert Topology'},
['CITEREFSchulenberg2010'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulenberg2013'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1980'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1983'] = {'Bach\'s compositions (sources)'},
['CITEREFSchulze1984'] = {'Bach\'s compositions (sources)'},
['CITEREFSchwieterman2001'] = {'Schwieterman-Leaves-Eastern'},
['CITEREFScottNegus2011'] = {'Scott-Negus-Cellar Door'},
['CITEREFScribbins1970'] = {'Scribbins-Hiawatha'},
['CITEREFScribbins2008'] = {'Scribbins-400-2008', 'Scribbins-Remembered'},
['CITEREFSearle'] = {'Cite sslidx'},
['CITEREFSegal1982'] = template_names['Iranica'],
['CITEREFSellwood1983'] = template_names['Cam_Hist_Iran'],
['CITEREFSemmensGoldfinch2000'] = {'Book-Semmens-Goldfinch-How Steam Locomotives Really Work'},
['CITEREFSemsarZand2008'] = {'Encyclopaedia Islamica'},
['CITEREFSetton1975'] = {'Setton-A History of the Crusades'},
['CITEREFSetton1976'] = {'The Papacy and the Levant'},
['CITEREFSetton1978'] = {'The Papacy and the Levant'},
['CITEREFSetton1984'] = {'The Papacy and the Levant'},
['CITEREFSettonHazard1975'] = {'Setton-A History of the Crusades'},
['CITEREFSfyroeras1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFShahbazi1986'] = template_names['Iranica'],
['CITEREFShahbazi1987'] = template_names['Iranica'],
['CITEREFShahbazi1988'] = template_names['Iranica'],
['CITEREFShahbazi1989'] = template_names['Iranica'],
['CITEREFShahbazi1991'] = template_names['Iranica'],
['CITEREFShahbazi1994'] = template_names['Iranica'],
['CITEREFShahbazi2002'] = template_names['Iranica'],
['CITEREFShahbazi2003'] = template_names['Iranica'],
['CITEREFShahbazi2004'] = template_names['Iranica'],
['CITEREFShahbazi2005'] = template_names['Iranica'],
['CITEREFShahbaziBosworth1990'] = template_names['Iranica'],
['CITEREFShahbaziRichter-Bernburg2002'] = template_names['Iranica'],
['CITEREFShaki1991'] = template_names['Iranica'],
['CITEREFShaughnessy1997'] = {'Shaughnessy-DH'},
['CITEREFShaw1978'] = {'Shaw-RailroadAccidents'},
['CITEREFShayegan2004'] = template_names['Iranica'],
['CITEREFShayesteh2013'] = template_names['Iranica'],
['CITEREFSheikhsofla2018'] = {'Encyclopaedia Islamica'},
['CITEREFShindo2004'] = {'Kaneto-shindo-shinario-jinsei'},
['CITEREFShoarian-SattariRezaeeNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFShoshani2005'] = {'MSW3 Shoshani'},
['CITEREFShtern2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSiegele1957'] = {'Bach\'s compositions (sources)'},
['CITEREFSilanos2014'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFSilke2006'] = {'O\'Donnell family tree'},
['CITEREFSimmons2005'] = {'MSW3 Chiroptera'},
['CITEREFSimon1966'] = {'Simon-Wines Australia'},
['CITEREFSimonWarner2011'] = {'Amtrak By the Numbers'},
['CITEREFSinclair1911'] = {'DCBL'},
['CITEREFSinger1905'] = {'Jewish Encyclopedia'},
['CITEREFSix1934'] = {'Cite Six', 'Cite six'},
['CITEREFSkjærvø2018'] = template_names['ODLA'],
['CITEREFSkoulatos1980'] = {'Les personnages byzantins de l\'Alexiade'},
['CITEREFSloan1964'] = {'Sloan1964'},
['CITEREFSmith1854'] = {'Cite DGRG', 'DGRG'},
['CITEREFSmith1870'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1873'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1876'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith1880'] = {'DGRBM', 'Cite DGRBM'},
['CITEREFSmith2010'] = {'Smith-Cruise Ships-2010'},
['CITEREFSolomentsev2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSolomon2000'] = {'Solomon-American Diesel', 'Solomon-UP'},
['CITEREFSolomon2003'] = {'Solomon-Masterpieces'},
['CITEREFSolomon2004'] = {'Solomon-Amtrak'},
['CITEREFSolomon2005'] = {'Solomon-SP-Passenger'},
['CITEREFSolomon2006'] = {'Solomon-EMD Locomotives'},
['CITEREFSolomon2011'] = {'Solomon-Modern Diesel'},
['CITEREFSolomon2014'] = {'Solomon-GE and EMD'},
['CITEREFSolomonSchafer2007'] = {'Solomon-New York Central'},
['CITEREFSolopova2009'] = template_names['ME-ref'],
['CITEREFSoucek1982'] = template_names['Iranica'],
['CITEREFSoucek1983'] = template_names['Iranica'],
['CITEREFSoustal1991'] = {'Tabula Imperii Byzantini'},
['CITEREFSoustalKoder1981'] = {'Tabula Imperii Byzantini'},
['CITEREFSpielhoff1991'] = {'Spielhoff-EL'},
['CITEREFSpitta1894'] = {'Bach\'s compositions (sources)'},
['CITEREFSpitta1899'] = {'Bach\'s compositions (sources)'},
['CITEREFSpringirth2016'] = {'Springirth-Philadelphia'},
['CITEREFSpuhler1986'] = template_names['Cam_Hist_Iran'],
['CITEREFSpuler1983'] = template_names['Iranica'],
['CITEREFSpuler1987'] = template_names['Iranica'],
['CITEREFStagner1993'] = {'Stagner-Transition'},
['CITEREFStansfield1999'] = {'Stansfield-AyrRenfrew'},
['CITEREFStatistical_Yearbook_of_the_Republic_of_Croatia_2015'] = {'Croatia Yearbook 2015'},
['CITEREFStaufer1993'] = {'Staufer-Pennsy_III'},
['CITEREFStauferPennypacker1962'] = {'Staufer-Pennsy'},
['CITEREFStauferPennypacker1968'] = {'Staufer-Pennsy Power II'},
['CITEREFStaunton1988'] = {'Australian Dictionary of Biography'},
['CITEREFSternFishmanTilove2006'] = {'Cite New York 2000', 'Cite NY2000', 'Cite ny2000', 'Cite NY 2000', 'Cite ny 2000'},
['CITEREFSternGilmartinMassengale1983'] = {'Cite New York 1900', 'Cite NY1900'},
['CITEREFSternGilmartinMellins1987'] = {'Cite New York 1930', 'Cite NY 1930', 'Cite NY1930', 'Cite ny1930', 'Cite ny 1930'},
['CITEREFSternMellinsFishman1995'] = {'Cite New York 1960', 'Cite NY1960', 'Cite NY 1960', 'Cite ny1960', 'Cite ny 1960'},
['CITEREFSternMellinsFishman1999'] = {'Cite New York 1880', 'Cite NY1880', 'Cite NY 1880', 'Cite ny1880', 'Cite ny 1880'},
['CITEREFStewart1974'] = {'When Steam Was King'},
['CITEREFStrachey1981'] = template_names['ME-ref'],
['CITEREFStrickland1983'] = {'Strickland Locomotive Directory'},
['CITEREFStähelin1909'] = {'Schaff-Herzog'},
['CITEREFSuetin2001'] = {'Springer', 'SpringerEOM'},
['CITEREFSundermann1988'] = template_names['Iranica'],
['CITEREFSusanne_Schurr1992'] = {'BBKL'},
['CITEREFSusanne_Siebert1992'] = {'BBKL'},
['CITEREFSvolopoulos1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSwartz1992'] = {'Swartz An Introduction to Functional Analysis'},
----------< T >----------
['CITEREFLondon_Gazette'] = {'London Gazette'},
['CITEREFTaber1977'] = {'Taber-DLW-19th'},
['CITEREFTaberTaber1980'] = {'Taber-DLW-20th-1'},
['CITEREFTaberTaber1981'] = {'Taber-DLW-20th-2'},
['CITEREFTafazzoli1999'] = template_names['Iranica'],
['CITEREFTafazzoli1999'] = {'Encyclopaedia Islamica'},
['CITEREFTafazzoli2000'] = template_names['Iranica'],
['CITEREFTalbot1991'] = template_names['ODB'],
['CITEREFTalbotKazhdan1991'] = template_names['ODB'],
['CITEREFTanındı2008'] = template_names['Iranica'],
['CITEREFTao2009'] = {'Cite Cambridge History of China'},
['CITEREFTer-Ghewondyan1976'] = {'The Arab Emirates in Bagratid Armenia'},
['CITEREFThe_London_Gazette1950'] = {'London Gazette'},
['CITEREFThe_London_Gazette_26_September_1919'] = {'London Gazette'},
['CITEREFThielemann2012'] = {'Bach\'s compositions (sources)'},
['CITEREFThomas1970'] = {'HistoryofParliament'},
['CITEREFThomas1971'] = {'Thomas-History-VI'},
['CITEREFThrush2010'] = {'HistoryofParliament'},
['CITEREFTikhomirov2001'] = {'Springer'},
['CITEREFTittel1966'] = {'Bach\'s compositions (sources)'},
['CITEREFTodt1996'] = {'BBKL'},
['CITEREFTodtVest2014'] = {'Tabula Imperii Byzantini'},
['CITEREFTolkien1937'] = template_names['ME-ref'],
['CITEREFTolkien1954'] = template_names['ME-ref'],
['CITEREFTolkien1955'] = template_names['ME-ref'],
['CITEREFTolkien1964'] = template_names['ME-ref'],
['CITEREFTolkien1966'] = template_names['ME-ref'],
['CITEREFTolkien1977'] = template_names['ME-ref'],
['CITEREFTolkien1980'] = template_names['ME-ref'],
['CITEREFTolkien1982'] = template_names['ME-ref'],
['CITEREFTolkien1983'] = template_names['ME-ref'],
['CITEREFTolkien1984'] = template_names['ME-ref'],
['CITEREFTolkien1985'] = template_names['ME-ref'],
['CITEREFTolkien1986'] = template_names['ME-ref'],
['CITEREFTolkien1987'] = template_names['ME-ref'],
['CITEREFTolkien1988'] = template_names['ME-ref'],
['CITEREFTolkien1989'] = template_names['ME-ref'],
['CITEREFTolkien1990'] = template_names['ME-ref'],
['CITEREFTolkien1992'] = template_names['ME-ref'],
['CITEREFTolkien1993'] = template_names['ME-ref'],
['CITEREFTolkien1994'] = template_names['ME-ref'],
['CITEREFTolkien1996'] = template_names['ME-ref'],
['CITEREFTolkien1998'] = template_names['ME-ref'],
['CITEREFTolkien1999'] = template_names['ME-ref'],
['CITEREFTolkien2007'] = template_names['ME-ref'],
['CITEREFTolkienSwan1978'] = template_names['ME-ref'],
['CITEREFTolkienTolkien1992'] = template_names['ME-ref'],
['CITEREFTonks1988'] = {'Tonks ironstone'},
['CITEREFTonks1989'] = {'Tonks ironstone'},
['CITEREFTonks1992'] = {'Tonks ironstone'},
['CITEREFTopping1975'] = {'Setton-A History of the Crusades'},
['CITEREFTorri2013'] = {'Bach\'s compositions (sources)'},
['CITEREFTougher2018'] = template_names['ODLA'],
['CITEREFToumanoff1986'] = template_names['Iranica'],
['CITEREFToumanoff2010'] = template_names['Iranica'],
['CITEREFToumanoffChaumont1987'] = template_names['Iranica'],
['CITEREFTourret1995'] = {'Tourret-Allied Military Locomotives'},
['CITEREFTrapp1991'] = template_names['ODB'],
['CITEREFTrappBeyerSturm-Schnabl1983'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTrappWaltherBeyer1976'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTrappWaltherBeyerSturm-Schnabl1978'] = {'Prosopographisches Lexikon der Palaiologenzeit'},
['CITEREFTreadgold1988'] = {'The Byzantine Revival, 780–842'},
['CITEREFTreadgold1997'] = {'A History of the Byzantine State and Society'},
['CITEREFTrèves2006'] = {'Trèves François Topological vector spaces, distributions and kernels'},
['CITEREFTucker2009'] = {'Encyclopaedia Islamica'},
['CITEREFTurim1998'] = {'Turim-oshima'},
['CITEREFTuring1950'] = {'Turing 1950'},
----------< U >----------
['CITEREFUS-NHub_Music_Deposit_31_(Klavierbüchlein_für_W._F._Bach)_at_Bach_Digital'] = {'Bach\'s compositions (sources)'},
['CITEREFUtas2002'] = template_names['Iranica'],
['CITEREFUwe_Eckardt2001'] = {'BBKL'},
['CITEREFunknown_author1881'] = {'Cite ADB'},
['CITEREFunknown_author1882'] = {'Cite ADB'},
----------< V >----------
['CITEREFVakalopoulos1975'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFVan_Cleve1969'] = {'Setton-A History of the Crusades'},
['CITEREFVan_Hoorickx1971'] = {'Schubert\'s compositions (references)'},
['CITEREFVan_Hoorickx_1974–1976'] = {'Schubert\'s compositions (references)'},
['CITEREFVan_Lint2018'] = template_names['ODLA'],
['CITEREFVan_Riemsdijk,_Compound_Locomotives'] = {'Book-Van Riemsdijk-Compound Locomotives'},
['CITEREFVan_Tricht2011'] = {'The Latin Renovatio of Byzantium'},
['CITEREFVandenberghen1989'] = {'Vandenberghen-SNCB12.2'},
['CITEREFVarzos1984'] = {'Η Γενεαλογία των Κομνηνών', 'Varzos-Genealogy of the Komnenoi'},
['CITEREFVasiliev1935'] = {'Byzance et les Arabes'},
['CITEREFVasiliev1968'] = {'Byzance et les Arabes'},
['CITEREFVendler1997'] = {'Shakespeare sonnets bibliography'},
['CITEREFVenetis2012'] = template_names['Iranica'],
['CITEREFVenn1954'] = {'VennAC'},
['CITEREFVesel1999'] = template_names['Iranica'],
['CITEREFVetter1713'] = {'Bach\'s compositions (sources)'},
['CITEREFVevainaCanepa2018'] = template_names['ODLA'],
['CITEREFVeysey1958'] = {'Veysey-PE-1958'},
['CITEREFVischer1912'] = {'Schaff-Herzog'},
['CITEREFVogelsang2003'] = template_names['Iranica'],
['CITEREFVolkmer1991'] = {'Volkmer-Pennsy-Electric'},
['CITEREFvan_Leyden1956'] = {'Bach\'s compositions (sources)'},
['CITEREFvan_Lint2018'] = template_names['ODLA'],
['CITEREFvon_Prantl1879'] = {'Cite ADB'},
----------< W >----------
['CITEREFWagnerBäzoldZschechLüderitz1990'] = {'Wagner-EFA2.3.2'},
['CITEREFWalter_Asmus1966'] = template_names['NDB'],
['CITEREFWayner1972'] = {'Wayner - Car names, numbers, consists'},
['CITEREFWayner1973'] = {'Wayner-Spotter-2nd'},
['CITEREFWebb2018'] = template_names['ODLA'],
['CITEREFWeber2016'] = template_names['Iranica'],
['CITEREFWechsler1979'] = {'Cite Cambridge History of China'},
['CITEREFWegman2008'] = {'Wegman-Illustrated'},
['CITEREFWeibel1994'] = {'Weibel IHA'},
['CITEREFWeinrebHibbertKeayKeay2008'] = {'London encyclopedia'},
['CITEREFWeisbrod1991'] = {'Weisbrod-EFA1.5'},
['CITEREFWeisbrodMüllerPetznik1978'] = {'Weisbrod-EFA1.2'},
['CITEREFWeiskopf1987'] = template_names['Iranica'],
['CITEREFWeiskopf1989'] = template_names['Iranica'],
['CITEREFWeiskopf1990'] = template_names['Iranica'],
['CITEREFWeiskopf1993'] = template_names['Iranica'],
['CITEREFWellhausen1927'] = {'The Arab Kingdom and its Fall'},
['CITEREFWells1982'] = {'Accents of English'},
['CITEREFWells2008'] = {'Cite LPD'},
['CITEREFWelsh2006'] = {'Welsh-Broadway'},
['CITEREFWelsh2008'] = {'Welsh-UP'},
['CITEREFWerner_Raupp2001'] = {'BBKL'},
['CITEREFWestcott1911'] = {'DCBL'},
['CITEREFWestermayer,_Georg1882'] = {'Cite ADB'},
['CITEREFWham1997'] = {'Wham-Ayrshire'},
['CITEREFWharton1991'] = template_names['ODB'],
['CITEREFWhishaw1842'] = {'Whishaw-RailofGB-2ndEd'},
['CITEREFWhishaw1969'] = {'Whishaw-RailofGB'},
['CITEREFWhite1985'] = {'White-Passenger-1985'},
['CITEREFWhite1993'] = {'White - American railroad freight car'},
['CITEREFWhiteWillenskyLeadon2010'] = {'Cite aia5'},
['CITEREFWhitehurst1973'] = {'Whitehurst GW Engines from 1940'},
['CITEREFWhittow1996'] = {'The Making of Byzantium, 600–1025'},
['CITEREFWickman1982'] = {'Country study'},
['CITEREFWiesehöfer1986'] = template_names['Iranica'],
['CITEREFWiesehöfer2018'] = template_names['ODLA'],
['CITEREFWilansky2013'] = {'Wilansky Modern Methods in Topological Vector Spaces'},
['CITEREFWillard2004'] = {'Willard General Topology'},
['CITEREFWilliams1998'] = {'Williams-Philadelphia'},
['CITEREFWilliams2003'] = {'Bach\'s compositions (sources)'},
['CITEREFWilliams2014'] = template_names['Iranica'],
['CITEREFWillis1750'] = {'Cite Notitia Parliamentaria'},
['CITEREFWilson2017'] = {'Wilson-Guide'},
['CITEREFWilsonFiske1891'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWilsonFiske1892'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWilsonFiske1900'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
['CITEREFWiltshire2000'] = {'Lloyd-Margaret River'},
['CITEREFWinfieldLyon2004'] = {'Winfield'},
['CITEREFWinkler1883'] = template_names['ADB'],
['CITEREFWitakowski2018'] = template_names['ODLA'],
['CITEREFWolff1969'] = {'Setton-A History of the Crusades'},
['CITEREFWollny2015'] = {'Bach\'s compositions (sources)'},
['CITEREFWood1907'] = {'Cite Nuttall', 'Nuttall'},
['CITEREFWoodsKilpatrick2005'] = {'MSW3 Hystricognathi'},
['CITEREFWorden2008'] = {'Country study'},
['CITEREFWortley2010'] = {'John Skylitzes: A Synopsis of Byzantine History, 811–1057'},
['CITEREFWozencraft2005'] = {'MSW3 Carnivora'},
['CITEREFWright1979'] = {'Cite Cambridge History of China'},
['CITEREFWright2000'] = {'Bach\'s compositions (sources)'},
['CITEREFWägliJacobi2010'] = {'Schienennetz Schweiz'},
['CITEREFWürsch2013'] = template_names['Iranica'],
----------< X >----------
----------< Y >----------
['CITEREFYakubova2016'] = template_names['Iranica'],
['CITEREFYarshater1983'] = template_names['Iranica'],
['CITEREFYarshater1986'] = template_names['Cam_Hist_Iran'],
['CITEREFYarshater1988'] = template_names['Iranica'],
['CITEREFYarshater2018'] = template_names['Iranica'],
['CITEREFYarshater2021'] = template_names['Iranica'],
['CITEREFYazici2002'] = template_names['Iranica'],
['CITEREFYenne2005'] = {'Yenne-Chiefs'},
['CITEREFYildiz2004'] = template_names['Iranica'],
['CITEREFYonge1990'] = {'Quail-4'},
['CITEREFYonge1994'] = {'Quail-5'},
['CITEREFYonge2002'] = {'Quail-5'},
['CITEREFYonge2008'] = {'Quail-5'},
['CITEREFYonge2016'] = {'Quail-2-2016'},
['CITEREFYongePadgettSzwenk2013'] = {'Quail-4-Paper-3rdEd'},
['CITEREFYusofi1990'] = template_names['Iranica'],
----------< Z >----------
['CITEREFZahn1889–1893'] = {'Bach\'s compositions (sources)'},
['CITEREFZakeri2021'] = template_names['Iranica'],
['CITEREFZarrinkoubNegahban2008'] = {'Encyclopaedia Islamica'},
['CITEREFZarrinkub1975'] = template_names['Cam_Hist_Iran'],
['CITEREFZeiniWiesehöfer2018'] = template_names['ODLA'],
['CITEREFZekulich2000'] = {'Zekulich-WineWA'},
['CITEREFZimmermann2004'] = {'Zimmermann-Burlington'},
['CITEREFZimmermann2007'] = {'Zimmermann-GrandLuxe'},
['CITEREFZuccaric._1747'] = {'Bach\'s compositions (sources)'},
----------< UNSORTED >----------
['CITEREFGazette27462'] = {'London Gazette'},
['CITEREFCawley2012'] = {'Medieval Lands by Charles Cawley'},
['CITEREFCrone2003'] = {'Slaves on Horses'},
['CITEREFΙστορία_του_Ελληνικού_Έθνους'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFSpyropoulos1928'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFPikros1977'] = {'Ιστορία του Ελληνικού Έθνους'},
['CITEREFÖz1993'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzgüdenli2008'] = template_names['Iranica'],
['CITEREFÖzaydın2002'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzaydın2006'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖzkuyumcu2006'] = {'TDV Encyclopedia of Islam'},
['CITEREFÖztürk2013'] = {'TDV Encyclopedia of Islam'},
['CITEREFΜεγάλη_Στρατιωτικὴ_καὶ_Ναυτικὴ_Ἐγκυκλοπαιδεία'] = {'Great Military and Naval Encyclopaedia'},
['CITEREFŞeşen1988'] = {'TDV Encyclopedia of Islam'},
['CITEREFFranke1994'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFTao2009'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFWechsler1979'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFWright1979'] = {'Cite Cambridge History of China', 'The Cambridge History of China'},
['CITEREFHistoric_England_Benty_Grange'] = {'NHLE'},
['CITEREFWalter1967'] = {'DBI', 'Dizionario Biografico degli Italiani'},
['CITEREFAliprantisBorder2006'] = {'Aliprantis Border Infinite Dimensional Analysis A Hitchhiker\'s Guide Third Edition'},
['CITEREFAmanat1985'] = template_names['Iranica'],
['CITEREFBaldwin1991'] = template_names['ODB'],
['CITEREFCallwell1999'] = {'Muni Chronology'},
['CITEREFHalmos1982'] = {'Halmos A Hilbert Space Problem Book 1982'},
['CITEREFHistoric_England'] = {'NHLE', 'National Heritage List for England'},
['CITEREFHitchins2001'] = template_names['Iranica'],
['CITEREFJohnson1906'] = {'BDA1906', 'Cite BDA1906'},
['CITEREFMachinery's_Handbook1996'] = {'MachinerysHandbook25e'},
['CITEREFMatthee2012'] = template_names['Iranica'],
['CITEREFNicholson2018'] = template_names['ODLA'],
['CITEREFNicol1968'] = {'The Byzantine Family of Kantakouzenos'},
['CITEREFWilsonFiske1889'] = {'Appletons\'', 'Cite Appletons\'', 'Appletons'},
}
--[[--------------------------< E X P O R T E D T A B L E S >------------------------------------------------
]]
return {
DNB_special_patterns = DNB_special_patterns,
DNB_template_names = template_names['DNB'],
special_patterns = special_patterns,
whitelist = whitelist,
wrapper_templates = wrapper_templates,
}
1aa09b54f21ebd45d55c0e11bec8783c21d7a4fa
Module:Format link
828
106
228
227
2022-09-04T15:24:59Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Format link
--
-- Makes a wikilink from the given link and display values. Links are escaped
-- with colons if necessary, and links to sections are detected and displayed
-- with " § " as a separator rather than the standard MediaWiki "#". Used in
-- the {{format link}} template.
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- lazily initialise [[Module:Arguments]]
local mError -- lazily initialise [[Module:Error]]
local yesno -- lazily initialise [[Module:Yesno]]
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getArgs(frame)
-- Fetches the arguments from the parent frame. Whitespace is trimmed and
-- blanks are removed.
mArguments = require('Module:Arguments')
return mArguments.getArgs(frame, {parentOnly = true})
end
local function removeInitialColon(s)
-- Removes the initial colon from a string, if present.
return s:match('^:?(.*)')
end
local function maybeItalicize(s, shouldItalicize)
-- Italicize s if s is a string and the shouldItalicize parameter is true.
if s and shouldItalicize then
return '<i>' .. s .. '</i>'
else
return s
end
end
local function parseLink(link)
-- Parse a link and return a table with the link's components.
-- These components are:
-- - link: the link, stripped of any initial colon (always present)
-- - page: the page name (always present)
-- - section: the page name (may be nil)
-- - display: the display text, if manually entered after a pipe (may be nil)
link = removeInitialColon(link)
-- Find whether a faux display value has been added with the {{!}} magic
-- word.
local prePipe, display = link:match('^(.-)|(.*)$')
link = prePipe or link
-- Find the page, if it exists.
-- For links like [[#Bar]], the page will be nil.
local preHash, postHash = link:match('^(.-)#(.*)$')
local page
if not preHash then
-- We have a link like [[Foo]].
page = link
elseif preHash ~= '' then
-- We have a link like [[Foo#Bar]].
page = preHash
end
-- Find the section, if it exists.
local section
if postHash and postHash ~= '' then
section = postHash
end
return {
link = link,
page = page,
section = section,
display = display,
}
end
local function formatDisplay(parsed, options)
-- Formats a display string based on a parsed link table (matching the
-- output of parseLink) and an options table (matching the input options for
-- _formatLink).
local page = maybeItalicize(parsed.page, options.italicizePage)
local section = maybeItalicize(parsed.section, options.italicizeSection)
if (not section) then
return page
elseif (not page) then
return mw.ustring.format('§ %s', section)
else
return mw.ustring.format('%s § %s', page, section)
end
end
local function missingArgError(target)
mError = require('Module:Error')
return mError.error{message =
'Error: no link or target specified! ([[' .. target .. '#Errors|help]])'
}
end
--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------
function p.formatLink(frame)
-- The formatLink export function, for use in templates.
yesno = require('Module:Yesno')
local args = getArgs(frame)
local link = args[1] or args.link
local target = args[3] or args.target
if not (link or target) then
return missingArgError('Template:Format link')
end
return p._formatLink{
link = link,
display = args[2] or args.display,
target = target,
italicizePage = yesno(args.italicizepage),
italicizeSection = yesno(args.italicizesection),
categorizeMissing = args.categorizemissing
}
end
function p._formatLink(options)
-- The formatLink export function, for use in modules.
checkType('_formatLink', 1, options, 'table')
local function check(key, expectedType) --for brevity
checkTypeForNamedArg(
'_formatLink', key, options[key], expectedType or 'string', true
)
end
check('link')
check('display')
check('target')
check('italicizePage', 'boolean')
check('italicizeSection', 'boolean')
check('categorizeMissing')
-- Normalize link and target and check that at least one is present
if options.link == '' then options.link = nil end
if options.target == '' then options.target = nil end
if not (options.link or options.target) then
return missingArgError('Module:Format link')
end
local parsed = parseLink(options.link)
local display = options.display or parsed.display
local catMissing = options.categorizeMissing
local category = ''
-- Find the display text
if not display then display = formatDisplay(parsed, options) end
-- Handle the target option if present
if options.target then
local parsedTarget = parseLink(options.target)
parsed.link = parsedTarget.link
parsed.page = parsedTarget.page
end
-- Test if page exists if a diagnostic category is specified
if catMissing and (mw.ustring.len(catMissing) > 0) then
local title = nil
if parsed.page then title = mw.title.new(parsed.page) end
if title and (not title.isExternal) and (not title.exists) then
category = mw.ustring.format('[[Category:%s]]', catMissing)
end
end
-- Format the result as a link
if parsed.link == display then
return mw.ustring.format('[[:%s]]%s', parsed.link, category)
else
return mw.ustring.format('[[:%s|%s]]%s', parsed.link, display, category)
end
end
--------------------------------------------------------------------------------
-- Derived convenience functions
--------------------------------------------------------------------------------
function p.formatPages(options, pages)
-- Formats an array of pages using formatLink and the given options table,
-- and returns it as an array. Nil values are not allowed.
local ret = {}
for i, page in ipairs(pages) do
ret[i] = p._formatLink{
link = page,
categorizeMissing = options.categorizeMissing,
italicizePage = options.italicizePage,
italicizeSection = options.italicizeSection
}
end
return ret
end
return p
b1a3177dc2ec780dc0a9720bfb64058aed46db95
Module:Hatnote
828
107
230
229
2022-09-04T15:24:59Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Hatnote --
-- --
-- This module produces hatnote links and links to related articles. It --
-- implements the {{hatnote}} and {{format link}} meta-templates and includes --
-- helper functions for other Lua hatnote modules. --
--------------------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg
local mArguments -- lazily initialise [[Module:Arguments]]
local yesno -- lazily initialise [[Module:Yesno]]
local formatLink -- lazily initialise [[Module:Format link]] ._formatLink
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local curNs = mw.title.getCurrentTitle().namespace
p.missingTargetCat =
--Default missing target category, exported for use in related modules
((curNs == 0) or (curNs == 14)) and
'Articles with hatnote templates targeting a nonexistent page' or nil
local function getArgs(frame)
-- Fetches the arguments from the parent frame. Whitespace is trimmed and
-- blanks are removed.
mArguments = require('Module:Arguments')
return mArguments.getArgs(frame, {parentOnly = true})
end
local function removeInitialColon(s)
-- Removes the initial colon from a string, if present.
return s:match('^:?(.*)')
end
function p.findNamespaceId(link, removeColon)
-- Finds the namespace id (namespace number) of a link or a pagename. This
-- function will not work if the link is enclosed in double brackets. Colons
-- are trimmed from the start of the link by default. To skip colon
-- trimming, set the removeColon parameter to false.
checkType('findNamespaceId', 1, link, 'string')
checkType('findNamespaceId', 2, removeColon, 'boolean', true)
if removeColon ~= false then
link = removeInitialColon(link)
end
local namespace = link:match('^(.-):')
if namespace then
local nsTable = mw.site.namespaces[namespace]
if nsTable then
return nsTable.id
end
end
return 0
end
function p.makeWikitextError(msg, helpLink, addTrackingCategory, title)
-- Formats an error message to be returned to wikitext. If
-- addTrackingCategory is not false after being returned from
-- [[Module:Yesno]], and if we are not on a talk page, a tracking category
-- is added.
checkType('makeWikitextError', 1, msg, 'string')
checkType('makeWikitextError', 2, helpLink, 'string', true)
yesno = require('Module:Yesno')
title = title or mw.title.getCurrentTitle()
-- Make the help link text.
local helpText
if helpLink then
helpText = ' ([[' .. helpLink .. '|help]])'
else
helpText = ''
end
-- Make the category text.
local category
if not title.isTalkPage -- Don't categorise talk pages
and title.namespace ~= 2 -- Don't categorise userspace
and yesno(addTrackingCategory) ~= false -- Allow opting out
then
category = 'Hatnote templates with errors'
category = mw.ustring.format(
'[[%s:%s]]',
mw.site.namespaces[14].name,
category
)
else
category = ''
end
return mw.ustring.format(
'<strong class="error">Error: %s%s.</strong>%s',
msg,
helpText,
category
)
end
function p.disambiguate(page, disambiguator)
-- Formats a page title with a disambiguation parenthetical,
-- i.e. "Example" → "Example (disambiguation)".
checkType('disambiguate', 1, page, 'string')
checkType('disambiguate', 2, disambiguator, 'string', true)
disambiguator = disambiguator or 'disambiguation'
return mw.ustring.format('%s (%s)', page, disambiguator)
end
function p.defaultClasses(inline)
-- Provides the default hatnote classes as a space-separated string; useful
-- for hatnote-manipulation modules like [[Module:Hatnote group]].
return
(inline == 1 and 'hatnote-inline' or 'hatnote') .. ' ' ..
'navigation-not-searchable'
end
--------------------------------------------------------------------------------
-- Hatnote
--
-- Produces standard hatnote text. Implements the {{hatnote}} template.
--------------------------------------------------------------------------------
function p.hatnote(frame)
local args = getArgs(frame)
local s = args[1]
if not s then
return p.makeWikitextError(
'no text specified',
'Template:Hatnote#Errors',
args.category
)
end
return p._hatnote(s, {
extraclasses = args.extraclasses,
selfref = args.selfref
})
end
function p._hatnote(s, options)
checkType('_hatnote', 1, s, 'string')
checkType('_hatnote', 2, options, 'table', true)
options = options or {}
local inline = options.inline
local hatnote = mw.html.create(inline == 1 and 'span' or 'div')
local extraclasses
if type(options.extraclasses) == 'string' then
extraclasses = options.extraclasses
end
hatnote
:attr('role', 'note')
:addClass(p.defaultClasses(inline))
:addClass(extraclasses)
:addClass(options.selfref and 'selfref' or nil)
:wikitext(s)
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Module:Hatnote/styles.css' }
} .. tostring(hatnote)
end
return p
7a49bd6a35a51b9e77a9c2c6f8f09a4738d7d68e
Module:Hatnote/styles.css
828
108
232
231
2022-09-04T15:24:59Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp|small=y}} */
.hatnote {
font-style: italic;
}
/* Limit structure CSS to divs because of [[Module:Hatnote inline]] */
div.hatnote {
/* @noflip */
padding-left: 1.6em;
margin-bottom: 0.5em;
}
.hatnote i {
font-style: normal;
}
/* The templatestyles element inserts a link element before hatnotes.
* TODO: Remove link if/when WMF resolves T200206 */
.hatnote + link + .hatnote {
margin-top: -0.5em;
}
44680ffd6e888866df2cdfa0341af9c7b97da94c
Module:Hatnote list
828
109
234
233
2022-09-04T15:25:00Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Module:Hatnote list --
-- --
-- This module produces and formats lists for use in hatnotes. In particular, --
-- it implements the for-see list, i.e. lists of "For X, see Y" statements, --
-- as used in {{about}}, {{redirect}}, and their variants. Also introduced --
-- are andList & orList helpers for formatting lists with those conjunctions. --
--------------------------------------------------------------------------------
local mArguments --initialize lazily
local mFormatLink = require('Module:Format link')
local mHatnote = require('Module:Hatnote')
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local p = {}
--------------------------------------------------------------------------------
-- List stringification helper functions
--
-- These functions are used for stringifying lists, usually page lists inside
-- the "Y" portion of "For X, see Y" for-see items.
--------------------------------------------------------------------------------
--default options table used across the list stringification functions
local stringifyListDefaultOptions = {
conjunction = "and",
separator = ",",
altSeparator = ";",
space = " ",
formatted = false
}
--Searches display text only
local function searchDisp(haystack, needle)
return string.find(
string.sub(haystack, (string.find(haystack, '|') or 0) + 1), needle
)
end
-- Stringifies a list generically; probably shouldn't be used directly
local function stringifyList(list, options)
-- Type-checks, defaults, and a shortcut
checkType("stringifyList", 1, list, "table")
if #list == 0 then return nil end
checkType("stringifyList", 2, options, "table", true)
options = options or {}
for k, v in pairs(stringifyListDefaultOptions) do
if options[k] == nil then options[k] = v end
end
local s = options.space
-- Format the list if requested
if options.formatted then
list = mFormatLink.formatPages(
{categorizeMissing = mHatnote.missingTargetCat}, list
)
end
-- Set the separator; if any item contains it, use the alternate separator
local separator = options.separator
for k, v in pairs(list) do
if searchDisp(v, separator) then
separator = options.altSeparator
break
end
end
-- Set the conjunction, apply Oxford comma, and force a comma if #1 has "§"
local conjunction = s .. options.conjunction .. s
if #list == 2 and searchDisp(list[1], "§") or #list > 2 then
conjunction = separator .. conjunction
end
-- Return the formatted string
return mw.text.listToText(list, separator .. s, conjunction)
end
--DRY function
function p.conjList (conj, list, fmt)
return stringifyList(list, {conjunction = conj, formatted = fmt})
end
-- Stringifies lists with "and" or "or"
function p.andList (...) return p.conjList("and", ...) end
function p.orList (...) return p.conjList("or", ...) end
--------------------------------------------------------------------------------
-- For see
--
-- Makes a "For X, see [[Y]]." list from raw parameters. Intended for the
-- {{about}} and {{redirect}} templates and their variants.
--------------------------------------------------------------------------------
--default options table used across the forSee family of functions
local forSeeDefaultOptions = {
andKeyword = 'and',
title = mw.title.getCurrentTitle().text,
otherText = 'other uses',
forSeeForm = 'For %s, see %s.',
}
--Collapses duplicate punctuation
local function punctuationCollapse (text)
local replacements = {
["%.%.$"] = ".",
["%?%.$"] = "?",
["%!%.$"] = "!",
["%.%]%]%.$"] = ".]]",
["%?%]%]%.$"] = "?]]",
["%!%]%]%.$"] = "!]]"
}
for k, v in pairs(replacements) do text = string.gsub(text, k, v) end
return text
end
-- Structures arguments into a table for stringification, & options
function p.forSeeArgsToTable (args, from, options)
-- Type-checks and defaults
checkType("forSeeArgsToTable", 1, args, 'table')
checkType("forSeeArgsToTable", 2, from, 'number', true)
from = from or 1
checkType("forSeeArgsToTable", 3, options, 'table', true)
options = options or {}
for k, v in pairs(forSeeDefaultOptions) do
if options[k] == nil then options[k] = v end
end
-- maxArg's gotten manually because getArgs() and table.maxn aren't friends
local maxArg = 0
for k, v in pairs(args) do
if type(k) == 'number' and k > maxArg then maxArg = k end
end
-- Structure the data out from the parameter list:
-- * forTable is the wrapper table, with forRow rows
-- * Rows are tables of a "use" string & a "pages" table of pagename strings
-- * Blanks are left empty for defaulting elsewhere, but can terminate list
local forTable = {}
local i = from
local terminated = false
-- If there is extra text, and no arguments are given, give nil value
-- to not produce default of "For other uses, see foo (disambiguation)"
if options.extratext and i > maxArg then return nil end
-- Loop to generate rows
repeat
-- New empty row
local forRow = {}
-- On blank use, assume list's ended & break at end of this loop
forRow.use = args[i]
if not args[i] then terminated = true end
-- New empty list of pages
forRow.pages = {}
-- Insert first pages item if present
table.insert(forRow.pages, args[i + 1])
-- If the param after next is "and", do inner loop to collect params
-- until the "and"'s stop. Blanks are ignored: "1|and||and|3" → {1, 3}
while args[i + 2] == options.andKeyword do
if args[i + 3] then
table.insert(forRow.pages, args[i + 3])
end
-- Increment to next "and"
i = i + 2
end
-- Increment to next use
i = i + 2
-- Append the row
table.insert(forTable, forRow)
until terminated or i > maxArg
return forTable
end
-- Stringifies a table as formatted by forSeeArgsToTable
function p.forSeeTableToString (forSeeTable, options)
-- Type-checks and defaults
checkType("forSeeTableToString", 1, forSeeTable, "table", true)
checkType("forSeeTableToString", 2, options, "table", true)
options = options or {}
for k, v in pairs(forSeeDefaultOptions) do
if options[k] == nil then options[k] = v end
end
-- Stringify each for-see item into a list
local strList = {}
if forSeeTable then
for k, v in pairs(forSeeTable) do
local useStr = v.use or options.otherText
local pagesStr =
p.andList(v.pages, true) or
mFormatLink._formatLink{
categorizeMissing = mHatnote.missingTargetCat,
link = mHatnote.disambiguate(options.title)
}
local forSeeStr = string.format(options.forSeeForm, useStr, pagesStr)
forSeeStr = punctuationCollapse(forSeeStr)
table.insert(strList, forSeeStr)
end
end
if options.extratext then table.insert(strList, punctuationCollapse(options.extratext..'.')) end
-- Return the concatenated list
return table.concat(strList, ' ')
end
-- Produces a "For X, see [[Y]]" string from arguments. Expects index gaps
-- but not blank/whitespace values. Ignores named args and args < "from".
function p._forSee (args, from, options)
local forSeeTable = p.forSeeArgsToTable(args, from, options)
return p.forSeeTableToString(forSeeTable, options)
end
-- As _forSee, but uses the frame.
function p.forSee (frame, from, options)
mArguments = require('Module:Arguments')
return p._forSee(mArguments.getArgs(frame), from, options)
end
return p
d0828422b1aa0d0d0092d699d059c9e882260398
Module:Navbar
828
110
236
235
2022-09-04T15:25:00Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local p = {}
local cfg = mw.loadData('Module:Navbar/configuration')
local function get_title_arg(is_collapsible, template)
local title_arg = 1
if is_collapsible then title_arg = 2 end
if template then title_arg = 'template' end
return title_arg
end
local function choose_links(template, args)
-- The show table indicates the default displayed items.
-- view, talk, edit, hist, move, watch
-- TODO: Move to configuration.
local show = {true, true, true, false, false, false}
if template then
show[2] = false
show[3] = false
local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6,
talk = 2, edit = 3, hist = 4, move = 5, watch = 6}
-- TODO: Consider removing TableTools dependency.
for _, v in ipairs(require ('Module:TableTools').compressSparseArray(args)) do
local num = index[v]
if num then show[num] = true end
end
end
local remove_edit_link = args.noedit
if remove_edit_link then show[3] = false end
return show
end
local function add_link(link_description, ul, is_mini, font_style)
local l
if link_description.url then
l = {'[', '', ']'}
else
l = {'[[', '|', ']]'}
end
ul:tag('li')
:addClass('nv-' .. link_description.full)
:wikitext(l[1] .. link_description.link .. l[2])
:tag(is_mini and 'abbr' or 'span')
:attr('title', link_description.html_title)
:cssText(font_style)
:wikitext(is_mini and link_description.mini or link_description.full)
:done()
:wikitext(l[3])
:done()
end
local function make_list(title_text, has_brackets, displayed_links, is_mini, font_style)
local title = mw.title.new(mw.text.trim(title_text), cfg.title_namespace)
if not title then
error(cfg.invalid_title .. title_text)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''
-- TODO: Get link_descriptions and show into the configuration module.
-- link_descriptions should be easier...
local link_descriptions = {
{ ['mini'] = 'v', ['full'] = 'view', ['html_title'] = 'View this template',
['link'] = title.fullText, ['url'] = false },
{ ['mini'] = 't', ['full'] = 'talk', ['html_title'] = 'Discuss this template',
['link'] = talkpage, ['url'] = false },
{ ['mini'] = 'e', ['full'] = 'edit', ['html_title'] = 'Edit this template',
['link'] = title:fullUrl('action=edit'), ['url'] = true },
{ ['mini'] = 'h', ['full'] = 'hist', ['html_title'] = 'History of this template',
['link'] = title:fullUrl('action=history'), ['url'] = true },
{ ['mini'] = 'm', ['full'] = 'move', ['html_title'] = 'Move this template',
['link'] = mw.title.new('Special:Movepage'):fullUrl('target='..title.fullText), ['url'] = true },
{ ['mini'] = 'w', ['full'] = 'watch', ['html_title'] = 'Watch this template',
['link'] = title:fullUrl('action=watch'), ['url'] = true }
}
local ul = mw.html.create('ul')
if has_brackets then
ul:addClass(cfg.classes.brackets)
:cssText(font_style)
end
for i, _ in ipairs(displayed_links) do
if displayed_links[i] then add_link(link_descriptions[i], ul, is_mini, font_style) end
end
return ul:done()
end
function p._navbar(args)
-- TODO: We probably don't need both fontstyle and fontcolor...
local font_style = args.fontstyle
local font_color = args.fontcolor
local is_collapsible = args.collapsible
local is_mini = args.mini
local is_plain = args.plain
local collapsible_class = nil
if is_collapsible then
collapsible_class = cfg.classes.collapsible
if not is_plain then is_mini = 1 end
if font_color then
font_style = (font_style or '') .. '; color: ' .. font_color .. ';'
end
end
local navbar_style = args.style
local div = mw.html.create():tag('div')
div
:addClass(cfg.classes.navbar)
:addClass(cfg.classes.plainlinks)
:addClass(cfg.classes.horizontal_list)
:addClass(collapsible_class) -- we made the determination earlier
:cssText(navbar_style)
if is_mini then div:addClass(cfg.classes.mini) end
local box_text = (args.text or cfg.box_text) .. ' '
-- the concatenated space guarantees the box text is separated
if not (is_mini or is_plain) then
div
:tag('span')
:addClass(cfg.classes.box_text)
:cssText(font_style)
:wikitext(box_text)
end
local template = args.template
local displayed_links = choose_links(template, args)
local has_brackets = args.brackets
local title_arg = get_title_arg(is_collapsible, template)
local title_text = args[title_arg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local list = make_list(title_text, has_brackets, displayed_links, is_mini, font_style)
div:node(list)
if is_collapsible then
local title_text_class
if is_mini then
title_text_class = cfg.classes.collapsible_title_mini
else
title_text_class = cfg.classes.collapsible_title_full
end
div:done()
:tag('div')
:addClass(title_text_class)
:cssText(font_style)
:wikitext(args[1])
end
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = cfg.templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
return p._navbar(require('Module:Arguments').getArgs(frame))
end
return p
a5c8d3a8f8beb18984ea7f145ddbdf88a065d23e
Module:Navbar/configuration
828
111
238
237
2022-09-04T15:25:00Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
return {
['templatestyles'] = 'Module:Navbar/styles.css',
['box_text'] = 'This box: ', -- default text box when not plain or mini
['title_namespace'] = 'Template', -- namespace to default to for title
['invalid_title'] = 'Invalid title ',
['classes'] = { -- set a line to nil if you don't want it
['navbar'] = 'navbar',
['plainlinks'] = 'plainlinks', -- plainlinks
['horizontal_list'] = 'hlist', -- horizontal list class
['mini'] = 'navbar-mini', -- class indicating small links in the navbar
['this_box'] = 'navbar-boxtext',
['brackets'] = 'navbar-brackets',
-- 'collapsible' is the key for a class to indicate the navbar is
-- setting up the collapsible element in addition to the normal
-- navbar.
['collapsible'] = 'navbar-collapse',
['collapsible_title_mini'] = 'navbar-ct-mini',
['collapsible_title_full'] = 'navbar-ct-full'
}
}
bbf3d86b48a5b40835e8e232ae9821e6bca390ec
Module:Navbar/styles.css
828
112
240
239
2022-09-04T15:25:01Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp|small=yes}} */
.navbar {
display: inline;
font-size: 88%;
font-weight: normal;
}
.navbar-collapse {
float: left;
text-align: left;
}
.navbar-boxtext {
word-spacing: 0;
}
.navbar ul {
display: inline-block;
white-space: nowrap;
line-height: inherit;
}
.navbar-brackets::before {
margin-right: -0.125em;
content: '[ ';
}
.navbar-brackets::after {
margin-left: -0.125em;
content: ' ]';
}
.navbar li {
word-spacing: -0.125em;
}
.navbar a > span,
.navbar a > abbr {
text-decoration: inherit;
}
.navbar-mini abbr {
font-variant: small-caps;
border-bottom: none;
text-decoration: none;
cursor: inherit;
}
.navbar-ct-full {
font-size: 114%;
margin: 0 7em;
}
.navbar-ct-mini {
font-size: 114%;
margin: 0 4em;
}
9d4056f949b4f0b159e3d40dfb1a5f01e72f9571
Module:Navbox
828
113
242
241
2022-09-04T15:25:01Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local p = {}
local navbar = require('Module:Navbar')._navbar
local cfg = mw.loadData('Module:Navbox/configuration')
local getArgs -- lazily initialized
local args
local format = string.format
local function striped(wikitext, border)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = cfg.category.orphan
if border == cfg.keyword.border_subgroup and args[cfg.arg.orphan] ~= cfg.keyword.orphan_yes then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = cfg.class.navbox_odd_part, cfg.class.navbox_even_part
if args[cfg.arg.evenodd] then
if args[cfg.arg.evenodd] == cfg.keyword.evenodd_swap then
first, second = second, first
else
first = args[cfg.arg.evenodd]
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(cfg.marker.regex, changer)) -- () omits gsub count
end
local function processItem(item, nowrapitems)
if item:sub(1, 2) == '{|' then
-- Applying nowrap to lines in a table does not make sense.
-- Add newlines to compensate for trim of x in |parm=x in a template.
return '\n' .. item ..'\n'
end
if nowrapitems == cfg.keyword.nowrapitems_yes then
local lines = {}
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
if prefix and not content:match(cfg.pattern.nowrap) then
line = format(cfg.nowrap_item, prefix, content)
end
table.insert(lines, line)
end
item = table.concat(lines, '\n')
end
if item:match('^[*:;#]') then
return '\n' .. item ..'\n'
end
return item
end
-- we will want this later when we want to add tstyles for hlist/plainlist
local function has_navbar()
return args[cfg.arg.navbar] ~= cfg.keyword.navbar_off
and args[cfg.arg.navbar] ~= cfg.keyword.navbar_plain
and (
args[cfg.arg.name]
or mw.getCurrentFrame():getParent():getTitle():gsub(cfg.pattern.sandbox, '')
~= cfg.pattern.navbox
)
end
local function renderNavBar(titleCell)
if has_navbar() then
titleCell:wikitext(navbar{
[cfg.navbar.name] = args[cfg.arg.name],
[cfg.navbar.mini] = 1,
[cfg.navbar.fontstyle] = (args[cfg.arg.basestyle] or '') .. ';' ..
(args[cfg.arg.titlestyle] or '') ..
';background:none transparent;border:none;box-shadow:none;padding:0;'
})
end
end
local function renderTitleRow(tbl)
if not args[cfg.arg.title] then return end
local titleRow = tbl:tag('tr')
local titleCell = titleRow:tag('th'):attr('scope', 'col')
local titleColspan = 2
if args[cfg.arg.imageleft] then titleColspan = titleColspan + 1 end
if args[cfg.arg.image] then titleColspan = titleColspan + 1 end
titleCell
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.titlestyle])
:addClass(cfg.class.navbox_title)
:attr('colspan', titleColspan)
renderNavBar(titleCell)
titleCell
:tag('div')
-- id for aria-labelledby attribute
:attr('id', mw.uri.anchorEncode(args[cfg.arg.title]))
:addClass(args[cfg.arg.titleclass])
:css('font-size', '114%')
:css('margin', '0 4em')
:wikitext(processItem(args[cfg.arg.title]))
end
local function getAboveBelowColspan()
local ret = 2
if args[cfg.arg.imageleft] then ret = ret + 1 end
if args[cfg.arg.image] then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl)
if not args[cfg.arg.above] then return end
tbl:tag('tr')
:tag('td')
:addClass(cfg.class.navbox_abovebelow)
:addClass(args[cfg.arg.aboveclass])
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.abovestyle])
:attr('colspan', getAboveBelowColspan())
:tag('div')
-- id for aria-labelledby attribute, if no title
:attr('id', args[cfg.arg.title] and nil or mw.uri.anchorEncode(args[cfg.arg.above]))
:wikitext(processItem(args[cfg.arg.above], args[cfg.arg.nowrapitems]))
end
local function renderBelowRow(tbl)
if not args[cfg.arg.below] then return end
tbl:tag('tr')
:tag('td')
:addClass(cfg.class.navbox_abovebelow)
:addClass(args[cfg.arg.belowclass])
:cssText(args[cfg.arg.basestyle])
:cssText(args[cfg.arg.belowstyle])
:attr('colspan', getAboveBelowColspan())
:tag('div')
:wikitext(processItem(args[cfg.arg.below], args[cfg.arg.nowrapitems]))
end
local function renderListRow(tbl, index, listnum, listnums_size)
local row = tbl:tag('tr')
if index == 1 and args[cfg.arg.imageleft] then
row
:tag('td')
:addClass(cfg.class.noviewer)
:addClass(cfg.class.navbox_image)
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '0 2px 0 0')
:cssText(args[cfg.arg.imageleftstyle])
:attr('rowspan', listnums_size)
:tag('div')
:wikitext(processItem(args[cfg.arg.imageleft]))
end
local group_and_num = format(cfg.arg.group_and_num, listnum)
local groupstyle_and_num = format(cfg.arg.groupstyle_and_num, listnum)
if args[group_and_num] then
local groupCell = row:tag('th')
-- id for aria-labelledby attribute, if lone group with no title or above
if listnum == 1 and not (args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group2]) then
groupCell
:attr('id', mw.uri.anchorEncode(args[cfg.arg.group1]))
end
groupCell
:attr('scope', 'row')
:addClass(cfg.class.navbox_group)
:addClass(args[cfg.arg.groupclass])
:cssText(args[cfg.arg.basestyle])
-- If groupwidth not specified, minimize width
:css('width', args[cfg.arg.groupwidth] or '1%')
groupCell
:cssText(args[cfg.arg.groupstyle])
:cssText(args[groupstyle_and_num])
:wikitext(args[group_and_num])
end
local listCell = row:tag('td')
if args[group_and_num] then
listCell
:addClass(cfg.class.navbox_list_with_group)
else
listCell:attr('colspan', 2)
end
if not args[cfg.arg.groupwidth] then
listCell:css('width', '100%')
end
local rowstyle -- usually nil so cssText(rowstyle) usually adds nothing
if index % 2 == 1 then
rowstyle = args[cfg.arg.oddstyle]
else
rowstyle = args[cfg.arg.evenstyle]
end
local list_and_num = format(cfg.arg.list_and_num, listnum)
local listText = args[list_and_num]
local oddEven = cfg.marker.oddeven
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find(cfg.pattern.navbox_title) and cfg.marker.restart or cfg.class.navbox_odd_part
end
local liststyle_and_num = format(cfg.arg.liststyle_and_num, listnum)
local listclass_and_num = format(cfg.arg.listclass_and_num, listnum)
listCell
:css('padding', '0')
:cssText(args[cfg.arg.liststyle])
:cssText(rowstyle)
:cssText(args[liststyle_and_num])
:addClass(cfg.class.navbox_list)
:addClass(cfg.class.navbox_part .. oddEven)
:addClass(args[cfg.arg.listclass])
:addClass(args[listclass_and_num])
:tag('div')
:css('padding',
(index == 1 and args[cfg.arg.list1padding]) or args[cfg.arg.listpadding] or '0 0.25em'
)
:wikitext(processItem(listText, args[cfg.arg.nowrapitems]))
if index == 1 and args[cfg.arg.image] then
row
:tag('td')
:addClass(cfg.class.noviewer)
:addClass(cfg.class.navbox_image)
:addClass(args[cfg.arg.imageclass])
:css('width', '1px') -- Minimize width
:css('padding', '0 0 0 2px')
:cssText(args[cfg.arg.imagestyle])
:attr('rowspan', listnums_size)
:tag('div')
:wikitext(processItem(args[cfg.arg.image]))
end
end
-- uses this now to make the needHlistCategory correct
-- to use later for when we add list styles via navbox
local function has_list_class(htmlclass)
local class_args = { -- rough order of probability of use
cfg.arg.bodyclass, cfg.arg.listclass, cfg.arg.aboveclass,
cfg.arg.belowclass, cfg.arg.titleclass, cfg.arg.navboxclass,
cfg.arg.groupclass, cfg.arg.imageclass
}
local patterns = {
'^' .. htmlclass .. '$',
'%s' .. htmlclass .. '$',
'^' .. htmlclass .. '%s',
'%s' .. htmlclass .. '%s'
}
for _, arg in ipairs(class_args) do
for _, pattern in ipairs(patterns) do
if mw.ustring.find(args[arg] or '', pattern) then
return true
end
end
end
return false
end
local function needsHorizontalLists(border)
if border == cfg.keyword.border_subgroup or args[cfg.arg.tracking] == cfg.keyword.tracking_no then
return false
end
return not has_list_class(cfg.pattern.hlist) and not has_list_class(cfg.pattern.plainlist)
end
local function hasBackgroundColors()
for _, key in ipairs({cfg.arg.titlestyle, cfg.arg.groupstyle,
cfg.arg.basestyle, cfg.arg.abovestyle, cfg.arg.belowstyle}) do
if tostring(args[key]):find('background', 1, true) then
return true
end
end
return false
end
local function hasBorders()
for _, key in ipairs({cfg.arg.groupstyle, cfg.arg.basestyle,
cfg.arg.abovestyle, cfg.arg.belowstyle}) do
if tostring(args[key]):find('border', 1, true) then
return true
end
end
return false
end
local function isIllegible()
local styleratio = require('Module:Color contrast')._styleratio
for key, style in pairs(args) do
if tostring(key):match(cfg.pattern.style) then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(border)
local cats = {}
if needsHorizontalLists(border) then table.insert(cats, cfg.category.horizontal_lists) end
if hasBackgroundColors() then table.insert(cats, cfg.category.background_colors) end
if isIllegible() then table.insert(cats, cfg.category.illegible) end
if hasBorders() then table.insert(cats, cfg.category.borders) end
return cats
end
local function renderTrackingCategories(builder, border)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == cfg.keyword.subpage_doc or subpage == cfg.keyword.subpage_sandbox
or subpage == cfg.keyword.subpage_testcases then return end
for _, cat in ipairs(getTrackingCategories(border)) do
builder:wikitext('[[Category:' .. cat .. ']]')
end
end
local function renderMainTable(border, listnums)
local tbl = mw.html.create('table')
:addClass(cfg.class.nowraplinks)
:addClass(args[cfg.arg.bodyclass])
local state = args[cfg.arg.state]
if args[cfg.arg.title] and state ~= cfg.keyword.state_plain and state ~= cfg.keyword.state_off then
if state == cfg.keyword.state_collapsed then
state = cfg.class.collapsed
end
tbl
:addClass(cfg.class.collapsible)
:addClass(state or cfg.class.autocollapse)
end
tbl:css('border-spacing', 0)
if border == cfg.keyword.border_subgroup or border == cfg.keyword.border_none then
tbl
:addClass(cfg.class.navbox_subgroup)
:cssText(args[cfg.arg.bodystyle])
:cssText(args[cfg.arg.style])
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass(cfg.class.navbox_inner)
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args[cfg.arg.innerstyle])
renderTitleRow(tbl)
renderAboveRow(tbl)
local listnums_size = #listnums
for i, listnum in ipairs(listnums) do
renderListRow(tbl, i, listnum, listnums_size)
end
renderBelowRow(tbl)
return tbl
end
local function add_navbox_styles()
local frame = mw.getCurrentFrame()
-- This is a lambda so that it doesn't need the frame as a parameter
local function add_user_styles(templatestyles)
if templatestyles and templatestyles ~= '' then
return frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
}
end
return ''
end
-- get templatestyles. load base from config so that Lua only needs to do
-- the work once of parser tag expansion
local base_templatestyles = cfg.templatestyles
local templatestyles = add_user_styles(args[cfg.arg.templatestyles])
local child_templatestyles = add_user_styles(args[cfg.arg.child_templatestyles])
-- The 'navbox-styles' div exists for two reasons:
-- 1. To wrap the styles to work around T200206 more elegantly. Instead
-- of combinatorial rules, this ends up being linear number of CSS rules.
-- 2. To allow MobileFrontend to rip the styles out with 'nomobile' such that
-- they are not dumped into the mobile view.
return mw.html.create('div')
:addClass(cfg.class.navbox_styles)
:addClass(cfg.class.nomobile)
:wikitext(base_templatestyles .. templatestyles .. child_templatestyles)
:done()
end
function p._navbox(navboxArgs)
args = navboxArgs
local listnums = {}
for k, _ in pairs(args) do
if type(k) == 'string' then
local listnum = k:match(cfg.pattern.listnum)
if listnum then table.insert(listnums, tonumber(listnum)) end
end
end
table.sort(listnums)
local border = mw.text.trim(args[cfg.arg.border] or args[1] or '')
if border == cfg.keyword.border_child then
border = cfg.keyword.border_subgroup
end
-- render the main body of the navbox
local tbl = renderMainTable(border, listnums)
local res = mw.html.create()
-- render the appropriate wrapper for the navbox, based on the border param
if border == cfg.keyword.border_none then
res:node(add_navbox_styles())
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args[cfg.arg.title] or args[cfg.arg.above] or (args[cfg.arg.group1]
and not args[cfg.arg.group2]) then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(
args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1]
)
)
else
nav:attr('aria-label', cfg.aria_label)
end
elseif border == cfg.keyword.border_subgroup then
-- We assume that this navbox is being rendered in a list cell of a
-- parent navbox, and is therefore inside a div with padding:0em 0.25em.
-- We start with a </div> to avoid the padding being applied, and at the
-- end add a <div> to balance out the parent's </div>
res
:wikitext('</div>')
:node(tbl)
:wikitext('<div>')
else
res:node(add_navbox_styles())
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass(cfg.class.navbox)
:addClass(args[cfg.arg.navboxclass])
:cssText(args[cfg.arg.bodystyle])
:cssText(args[cfg.arg.style])
:css('padding', '3px')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args[cfg.arg.title] or args[cfg.arg.above]
or (args[cfg.arg.group1] and not args[cfg.arg.group2]) then
nav:attr(
'aria-labelledby',
mw.uri.anchorEncode(args[cfg.arg.title] or args[cfg.arg.above] or args[cfg.arg.group1])
)
else
nav:attr('aria-label', cfg.aria_label)
end
end
if (args[cfg.arg.nocat] or cfg.keyword.nocat_false):lower() == cfg.keyword.nocat_false then
renderTrackingCategories(res, border)
end
return striped(tostring(res), border)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
args = getArgs(frame, {wrappers = {cfg.pattern.navbox}})
-- Read the arguments in the order they'll be output in, to make references
-- number in the right order.
local _
_ = args[cfg.arg.title]
_ = args[cfg.arg.above]
-- Limit this to 20 as covering 'most' cases (that's a SWAG) and because
-- iterator approach won't work here
for i = 1, 20 do
_ = args[format(cfg.arg.group_and_num, i)]
_ = args[format(cfg.arg.list_and_num, i)]
end
_ = args[cfg.arg.below]
return p._navbox(args)
end
return p
5bbd6589b208bd567b351b855083c132c16a0fb9
Module:Navbox/configuration
828
114
244
243
2022-09-04T15:25:01Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
return {
aria_label = 'Navbox',
nowrap_item = '%s<span class="nowrap">%s</span>',
templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Module:Navbox/styles.css' }
},
-- do not localize marker table
marker = {
oddeven = '\127_ODDEVEN_\127',
restart = '\127_ODDEVEN0_\127',
regex = '\127_ODDEVEN(%d?)_\127'
},
category = {
orphan = '[[Category:Navbox orphans]]',
horizontal_lists = 'Navigational boxes without horizontal lists',
background_colors = 'Navboxes using background colours',
illegible = 'Potentially illegible navboxes',
borders = 'Navboxes using borders',
},
keyword = {
border_subgroup = 'subgroup',
border_child = 'child',
border_none = 'none',
evenodd_swap = 'swap',
navbar_off = 'off',
navbar_plain = 'plain',
nocat_false = 'false',
nowrapitems_yes = 'yes',
orphan_yes = 'yes',
state_collapsed = 'collapsed',
state_off = 'off',
state_plain = 'plain',
subpage_doc = 'doc',
subpage_sandbox = 'sandbox',
subpage_testcases = 'testcases',
tracking_no = 'no'
},
class = {
autocollapse = 'autocollapse',
collapsible = 'mw-collapsible',
collapsed = 'mw-collapsed',
-- Warning
navbox = 'navbox', -- WMF currently hides 'navbox' from mobile,
-- so you probably shouldn't change the navbox class.
navbox_abovebelow = 'navbox-abovebelow',
navbox_group = 'navbox-group',
navbox_image = 'navbox-image',
navbox_inner = 'navbox-inner',
navbox_list = 'navbox-list',
navbox_list_with_group = 'navbox-list-with-group',
navbox_part = 'navbox-', -- do not l10n
navbox_styles = 'navbox-styles',
navbox_subgroup = 'navbox-subgroup',
navbox_title = 'navbox-title', -- l10n only if you change pattern.navbox_title below
navbox_odd_part = 'odd', -- do not l10n
navbox_even_part = 'even', -- do not l10n
nomobile = 'nomobile',
nowraplinks = 'nowraplinks',
noviewer = 'noviewer' -- used to remove images from MediaViewer
},
pattern = {
listnum = '^list(%d+)$',
sandbox = '/sandbox$',
navbox = 'Template:Navbox',
nowrap = '^<span class="nowrap">',
style = 'style$',
navbox_title = '<th[^>]*"navbox%-title"',
hlist = 'hlist',
plainlist = 'plainlist'
},
arg = {
above = 'above',
aboveclass = 'aboveclass',
abovestyle = 'abovestyle',
basestyle = 'basestyle',
bodyclass = 'bodyclass',
bodystyle = 'bodystyle',
border = 'border',
below = 'below',
belowclass = 'belowclass',
belowstyle = 'belowstyle',
evenodd = 'evenodd',
evenstyle = 'evenstyle',
group1 = 'group1',
group2 = 'group2',
group_and_num = 'group%d',
groupstyle_and_num = 'group%dstyle',
groupclass = 'groupclass',
groupstyle = 'groupstyle',
groupwidth = 'groupwidth',
innerstyle = 'innerstyle',
image = 'image',
imageclass = 'imageclass',
imageleft = 'imageleft',
imageleftstyle = 'imageleftstyle',
imagesetyle = 'imagestyle',
list_and_num = 'list%d',
listclass_and_num = 'list%dclass',
liststyle_and_num = 'list%dstyle',
list1padding = 'list1padding',
listclass = 'listclass',
listpadding = 'listpadding',
liststyle = 'liststyle',
name = 'name',
navbar = 'navbar',
navboxclass = 'navboxclass',
nocat = 'nocat',
nowrapitems = 'nowrapitems',
oddstyle = 'oddstyle',
orphan = 'orphan',
state = 'state',
style = 'style',
templatestyles = 'templatestyles',
child_templatestyles = 'child templatestyles',
title = 'title',
titleclass = 'titleclass',
titlestyle = 'titlestyle',
tracking = 'tracking'
},
-- names of navbar arguments
navbar = {
name = 1,
fontstyle = 'fontstyle',
mini = 'mini'
}
}
4a1fb97efbf7aa8a852959457b43eab420073194
Module:Navbox/styles.css
828
115
246
245
2022-09-04T15:25:02Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp|small=y}} */
.navbox {
box-sizing: border-box;
border: 1px solid #a2a9b1;
width: 100%;
clear: both;
font-size: 88%;
text-align: center;
padding: 1px;
margin: 1em auto 0; /* Prevent preceding content from clinging to navboxes */
}
.navbox .navbox {
margin-top: 0; /* No top margin for nested navboxes */
}
.navbox + .navbox, /* TODO: remove first line after transclusions have updated */
.navbox + .navbox-styles + .navbox {
margin-top: -1px; /* Single pixel border between adjacent navboxes */
}
.navbox-inner,
.navbox-subgroup {
width: 100%;
}
.navbox-group,
.navbox-title,
.navbox-abovebelow {
padding: 0.25em 1em;
line-height: 1.5em;
text-align: center;
}
.navbox-group {
white-space: nowrap;
/* @noflip */
text-align: right;
}
.navbox,
.navbox-subgroup {
background-color: #fdfdfd;
}
.navbox-list {
line-height: 1.5em;
border-color: #fdfdfd; /* Must match background color */
}
.navbox-list-with-group {
text-align: left;
border-left-width: 2px;
border-left-style: solid;
}
/* cell spacing for navbox cells */
/* Borders above 2nd, 3rd, etc. rows */
/* TODO: figure out how to replace tr as structure;
* with div structure it should be just a matter of first-child */
tr + tr > .navbox-abovebelow,
tr + tr > .navbox-group,
tr + tr > .navbox-image,
tr + tr > .navbox-list {
border-top: 2px solid #fdfdfd; /* Must match background color */
}
.navbox-title {
background-color: #ccf; /* Level 1 color */
}
.navbox-abovebelow,
.navbox-group,
.navbox-subgroup .navbox-title {
background-color: #ddf; /* Level 2 color */
}
.navbox-subgroup .navbox-group,
.navbox-subgroup .navbox-abovebelow {
background-color: #e6e6ff; /* Level 3 color */
}
.navbox-even {
background-color: #f7f7f7;
}
.navbox-odd {
background-color: transparent;
}
/* TODO: figure out how to remove reliance on td as structure */
.navbox .hlist td dl,
.navbox .hlist td ol,
.navbox .hlist td ul,
.navbox td.hlist dl,
.navbox td.hlist ol,
.navbox td.hlist ul {
padding: 0.125em 0;
}
.navbox .navbar {
display: block;
font-size: 100%;
}
.navbox-title .navbar {
/* @noflip */
float: left;
/* @noflip */
text-align: left;
/* @noflip */
margin-right: 0.5em;
}
e80b0d7a5770e6e105dab832deb6c37a5245ebc6
Module:Other uses
828
116
248
247
2022-09-04T15:25:02Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
local mHatnote = require('Module:Hatnote')
local mHatlist = require('Module:Hatnote list')
local mArguments --initialize lazily
local mTableTools --initialize lazily
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local p = {}
-- Produces standard {{other uses}} implementation
function p.otheruses(frame)
mArguments = require('Module:Arguments')
mTableTools = require('Module:TableTools')
local args = mTableTools.compressSparseArray(mArguments.getArgs(frame))
local title = mw.title.getCurrentTitle().prefixedText
return p._otheruses(args, {title=title})
end
--Implements "other [x]" templates with otherText supplied at invocation
function p.otherX(frame)
mArguments = require('Module:Arguments')
mTableTools = require('Module:TableTools')
local x = frame.args[1]
local args = mTableTools.compressSparseArray(
mArguments.getArgs(frame, {parentOnly = true})
)
local options = {
title = mw.title.getCurrentTitle().prefixedText,
otherText = x
}
return p._otheruses(args, options)
end
-- Main generator
function p._otheruses(args, options)
--Type-checks and defaults
checkType('_otheruses', 1, args, 'table', true)
args = args or {}
checkType('_otheruses', 2, options, 'table')
if not (options.defaultPage or options.title) then
error('No default title data provided in "_otheruses" options table', 2)
end
local emptyArgs = true
for k, v in pairs(args) do
if type(k) == 'number' then emptyArgs = false break end
end
if emptyArgs then
args = {
options.defaultPage or
mHatnote.disambiguate(options.title, options.disambiguator)
}
end
--Generate and return hatnote
local text = mHatlist.forSeeTableToString({{
use = options.otherText and "other " .. options.otherText or nil,
pages = args
}})
return mHatnote._hatnote(text)
end
return p
2497cafae11ffa785bced56bc9f3853cf3bce7b1
Module:Portal/images/a
828
117
250
249
2022-09-04T15:25:03Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[==[ This is the "A" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "A". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be
-- omitted.
]==]
return {
["airports"] = "Round Landmark Icon Airport.svg|link=|alt=",
["aarhus"] = "Coat of arms of Aarhus.svg|alt=icon",
["abkhazia"] = "Flag of Abkhazia.svg|border|link=|alt=flag",
["aboriginal peoples in canada"] = "Aboriginal War Veterans monument (close).JPG|alt=icon",
["abu dhabi"] = "Flag of Abu Dhabi.svg|border|link=|alt=flag",
["acipenseriformes"] = "Acipenser oxyrhynchus (edit).png|link=|alt=icon",
["actors and filmmakers"] = "Charlie Chaplin 1912.jpg|link=|alt=photo",
["ac/dc"] = "Acdc logo band.svg|link=|alt=",
["academy award"] = "Video-x-generic.svg|link=|alt=",
["acadia"] = "Flag of Acadia.svg|border|link=|alt=flag",
["acc"] = "ACC Map crop 2014.png|alt=icon",
["adelaide"] = "Escudo de Adelaida.png|alt=icon",
["adobe flash"] = "Adobe Flash Player v11 icon.png|link=|alt=logo",
["advent"] = "Candle4.png|alt=Advent candle",
["aerosmith"] = "Joe Perry 1.jpg|alt=icon",
["aerospace biography"] = "Armstrong-Spencom01.jpg|link=|alt=photo",
["aesthetics"] = "Morning Glory Flower square.jpg|alt=icon",
["afghanistan"] = "Flag of the Taliban.svg|border|link=|alt=flag",
["africa"] = "Africa (orthographic projection).svg|link=|alt=map",
["african american"] = "Kleed- Stichting Nationaal Museum van Wereldculturen - RV-5899-18 (cropped).jpg|alt=icon",
["african cuisine"] = "Africa icon.png|link=|alt=",
["african diaspora"] = "Moromi.png|link=|alt=map",
["african union"] = "Flag of the African Union.svg|border|link=|alt=flag",
["afro-eurasia"] = "Afro-Eurasia (orthographic projection).svg|link=|alt=map",
["agriculture"] = "Veranotrigo.jpg|alt=icon",
["agriculture and agronomy"] = "Veranotrigo.jpg|alt=icon",
["agropedia"] = "Farmer plowing in Fahrenwalde, Mecklenburg-Vorpommern, Germany.jpg|alt=icon",
["aguascalientes"] = "Flag of Aguascalientes.svg|border|link=|alt=flag",
["ahmadiyya"] = "White Minaret Symbol.png|alt=icon",
["ahmedabad"] = "Mosque of Sidi Sayed Jaali.JPG|alt=icon",
["ai"] = "ArtificialFictionBrain.png|alt=icon",
["ajman"] = "Flag of Ajman.svg|link=|alt=flag",
["akb48"] = "AKB48 logo2.svg|link=|alt=",
["alabama"] = "Flag of Alabama.svg|border|link=|alt=flag",
["alaska"] = "Flag of Alaska.svg|border|link=|alt=flag",
["albania"] = "Flag of Albania.svg|border|link=|alt=flag",
["albemarle county"] = "Monticello 2010-10-29.jpg|link=|alt=photo",
["alberta"] = "Flag of Alberta.svg|border|link=|alt=flag",
["alcoholic drinks"] = "Mitch (cocktail).jpg|link=|alt=",
["a-league"] = "Soccer ball.svg|alt=icon",
["algae"] = "Algae Graphic.svg|link=|alt=icon",
["algebra"] = "Arithmetic symbols.svg|link=|alt=",
["algeria"] = "Flag of Algeria.svg|border|link=|alt=flag",
["almaty"] = "Flag of Almaty.svg|alt=flag",
["alps"] = "Palü en Diavolezza.jpg|alt=icon",
["alternative medicine"] = "Rod of Asclepius2.svg|alt=icon",
["alternative rock"] = "Guitar 1.svg|link=|alt=icon",
["american animation"] = "Animation disc US.svg|link=|alt=icon",
["american cinema"] = "Cinema of the United States.svg|link=|alt=icon",
["american civil war"] = "Acw bs 7a.png|border|link=|alt=",
["american cuisine"] = "Americanbandstand-1.jpg|link=|alt=",
["american football"] = "American football.svg|link=|alt=icon",
["american football league"] = "AFL Trophy alt.png|link=|alt=trophy",
["american music"] = "Musical Notes USA.svg|link=|alt=icon",
["american old west"] = "Frederic Remington Dismounted Moving Led Horses.jpg|link=|alt=painting",
["american open wheel racing"] = "JuanMontoya2015Indy500.JPG|link=|alt=photo",
["american revolutionary war"] = "Washington Crossing the Delaware by Emanuel Leutze, MMA-NYC, 1851.jpg|border|link=|alt=",
["american samoa"] = "Flag of American Samoa.svg|border|link=|alt=flag",
["american television"] = "USA flag on television.svg|link=|alt=icon",
["americas"] = "Americas (orthographic projection).svg|link=|alt=map",
["amiga"] = "Boingball.png|link=|alt=",
["amphibians"] = "Frog (2546) - The Noun Project.svg|link=|alt=",
["amphibians and reptiles"] = "Lizardicon.svg|link=|alt=",
["amusement parks"] = "Roller Coaster Icon.svg|link=|alt=",
["anabaptism"] = "Dirk.willems.rescue.ncs.jpg|link=|alt=",
["analysis"] = "Nuvola apps kmplot.svg|alt=icon",
["analytical chemistry"] = "Nuvola apps edu science.svg|alt=icon",
["anarchism"] = "BlackFlagSymbol.svg|border|link=|alt=flag",
["andes"] = "Ausangate-hillside-MT.jpg|alt=",
["andorra la vella"] = "Flag of Andorra la Vella.svg|alt=flag",
["apples"] = "Apple icon 1.png|link=|alt=",
["argentine cuisine"] = "Argentine cuisine title.jpg|link=|alt=",
["anatomy"] = "Anatomy posture and body mechanics 08.web.jpg|alt=icon",
["ancient egypt"] = "Pyramidi aavikolla.png|link=|alt=",
["ancient germanic culture"] = "Mjollnir icon.png|link=|alt=",
["ancient greece"] = "Parthenon from west.jpg|link=|alt=",
["ancient japan"] = "Shiki no Fuji, Ōmuro fukin by Takahashi Shōtei.jpg|link=|alt=",
["ancient near east"] = "Babylonlion.JPG|link=|alt=",
["ancient rome"] = "SPQRomani.svg|link=|alt=",
["andaman and nicobar islands"] = "India Andaman and Nicobar Islands locator map.svg|border|link=|alt=map",
["andhra pradesh"] = "Archbridgegodavari.JPG|alt=icon",
["andorra"] = "Flag of Andorra.svg|border|link=|alt=flag",
["android (operating system)"] = "Android robot.svg|link=|alt=icon",
["anglicanism"] = "Canterbury cathedral.jpg|link=|alt=",
["anglo-saxon england"] = "Peterborough Chronicle cropped.jpg|link=|alt=",
["angola"] = "Flag of Angola.svg|border|link=|alt=flag",
["anguilla"] = "Flag of Anguilla.svg|border|link=|alt=flag",
["animal rights"] = "Paw (Animal Rights symbol).svg|alt=icon",
["animals"] = "Caribou from Wagon Trails.jpg|alt=icon",
["animation"] = "Animation disc.svg|alt=icon",
["animation/canadian animation work group"] = "Animation disc Maple Leaf.svg|alt=icon",
["anime and manga"] = "Wikipe-tan face.svg|alt=icon",
["antarctica"] = "Antarctica (orthographic projection).svg|link=|alt=map",
["anthropology"] = "Moai Easter Island InvMH-35-61-1.jpg|link=|alt=",
["antigua and barbuda"] = "Flag of Antigua and Barbuda.svg|border|link=|alt=flag",
["antwerp"] = "Coat of arms of Antwerp (City).svg|alt=icon",
["appalachia"] = "Appalachian region of United States.png|border|link=|alt=map",
["apple inc."] = "Apple logo black.svg|link=|alt=",
["applied science"] = "Metallurgy stub icon.svg|link=|alt=icon",
["aquarium fish"] = "Pterois antennata-3.jpg|link=|alt=",
["arab world"] = "Flag of the Arab League.svg|border|link=|alt=flag",
["arabic language"] = "Arabic-dad-letter.svg|link=Arabic language|alt=icon",
["archaeology"] = "Stonehenge Closeup.jpg|link=|alt=",
["architecture"] = "P parthenon.svg|alt=icon",
["arctic"] = "Arctic (orthographic projection).svg|link=|alt=map",
["argentina"] = "Flag of Argentina.svg|border|link=|alt=flag",
["arithmetic"] = "Arithmetic symbols.svg|link=|alt=",
["arizona"] = "Flag of Arizona.svg|border|link=|alt=flag",
["arkansas"] = "Flag of Arkansas.svg|border|link=|alt=flag",
["armenia"] = "Flag of Armenia.svg|border|link=|alt=flag",
["arminianism"] = "Arminius 5 flopped and cropped.png|link=|alt=",
["arunachal pradesh"] = "India Arunachal Pradesh locator map.svg|link=|alt=map",
["art"] = "Ballerina-icon.jpg|alt=icon",
["arthropods"] = "Cercophonius squama.jpg|alt=icon",
["artificial intelligence"] = "Animation2.gif|alt=icon",
["arts"] = "Nuvola apps package graphics.png|alt=icon",
["artsakh"] = "Flag of Artsakh.svg|border|link=|alt=flag",
["arts and entertainment"] = "Meryl in 1990.jpg|link=|alt=photo",
["aruba"] = "Flag of Aruba.svg|border|link=|alt=flag",
["asia"] = "Asia (orthographic projection).svg|alt=icon",
["asian games"] = "Asian Games logo01.png|link=|alt=",
["aspect ratio 1.000"] = "Flag of Switzerland.svg|link=|alt=image",
["aspect ratio 1.333"] = "Flag of Gabon.svg|link=|alt=image",
["aspect ratio 1.400"] = "Flag of Kosovo.svg|link=|alt=image",
["aspect ratio 1.500"] = "Flag of the European Union.svg|link=|alt=image",
["aspect ratio 1.667"] = "Flag of Bangladesh.svg|link=|alt=image",
["aspect ratio 2.000"] = "Flag of the United Kingdom.svg|link=|alt=image",
["assam"] = "Seal of Assam.png|link=|alt=",
["association football"] = "Soccer ball.svg|alt=icon",
["assyrians"] = "Flag of Assyria.svg|border|link=|alt=flag",
["astrobiology"] = "PIA01130 Interior of Europa.jpg|link=|alt=",
["astrology"] = "Astrologia-tynkä.jpg|link=|alt=",
["astronomy"] = "Crab Nebula.jpg|link=|alt=",
["atheism"] = "Atheism template.svg|alt=icon",
["athletics"] = "Athletics pictogram.svg|link=|alt=",
["atlanta"] = "Atlflag.svg|link=|alt=flag",
["atlantic ocean"] = "Atlantic Ocean - en IHO.png|link=|alt=map",
["atlas"] = "World map green.png|alt=icon",
["atmospheric science"] = "Cumulus clouds in fair weather.jpeg|link=|alt=icon",
["atoms"] = "Stylised atom with three Bohr model orbits and stylised nucleus.svg|link=|alt=",
["austin"] = "Sixth Street Austin.jpg|alt=icon",
["australasia"] = "Oceania (orthographic projection).svg|link=|alt=map",
["australia"] = "Flag of Australia.svg|border|link=|alt=flag",
["australian army"] = "Australian Army Emblem Transparent.png|border|link=|alt=icon",
["australian capital territory"] = "Flag of the Australian Capital Territory.svg|border|link=|alt=flag",
["australian continent"] = "Australia (orthographic projection).svg|link=|alt=map",
["australian roads"] = "Australia road sign W5-29.svg|alt=icon",
["australian rules football"] = "Sherrin-transparent.png|link=|alt=",
["austria"] = "Flag of Austria.svg|border|link=|alt=flag",
["austria-hungary"] = "Wappen Österreich-Ungarn 1916 (Klein).png|link=|alt=",
["automobiles"] = "Sportcar sergio luiz ara 01.svg|link=|alt=",
["automotive industry in japan"] = "Car with Driver-Silhouette.svg|link=|alt=",
["aviation"] = "Aviacionavion.png|link=|alt=",
["avril lavigne"] = "LetGo.jpg|alt=icon",
["ayyavazhi"] = "Ayyavazh logo transperent.png|alt=icon",
["azad kashmir"] = "Flag of Azad Kashmir.svg|border|link=|alt=flag",
["azerbaijan"] = "Flag of Azerbaijan.svg|border|link=|alt=flag",
["azores"] = "Flag of the Azores.svg|border|link=|alt=flag"
}
2ed9709a584c9486757ce4112bbf87096eb6b3be
Module:Portal bar
828
118
252
251
2022-09-04T15:25:03Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module implements {{portal bar}}.
require('Module:No globals')
-- determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''
local portalModule = require('Module:Portal'..sandbox)
local getImageName = portalModule._image
local checkPortals = portalModule._checkPortals
local processPortalArgs = portalModule._processPortalArgs
local yesno = require( 'Module:Yesno' )
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function sandboxVersion(s)
return isSandbox and s.."-sand" or s
end
-- Builds the portal bar used by {{portal bar}}.
function p._main( portals, args )
-- check for sensible args
args = type(args) == "table" and args or {}
-- Normalize arguments
for key, default in pairs({border=true,redlinks=false,tracking=true}) do
if args[key] == nil then args[key] = default end
args[key] = yesno(args[key], default)
end
local nav = mw.html.create( 'div' )
:addClass(sandboxVersion('portal-bar'))
:addClass( 'noprint metadata noviewer' )
:attr( 'role', 'navigation' )
:attr( 'aria-label' , 'Portals' )
:addClass(sandboxVersion(args.border and 'portal-bar-bordered' or 'portal-bar-unbordered'))
local trackingCat = ''
-- Allow any number of portals
args.minPortals = 0
args.maxPortals = -1
-- Check to see whether there are redlinks, filter out unless args.redlink is true
portals, trackingCat = checkPortals(portals, args)
nav:wikitext(trackingCat)
if #portals == 0 then
return trackingCat
end
local related = yesno(args.related)
if related then
nav:addClass(sandboxVersion('portal-bar-related'))
else
local header = nav:tag('span')
header:addClass(sandboxVersion('portal-bar-header'))
header:wikitext('[[Wikipedia:Contents/Portals|Portal]]')
if #portals > 1 then
header:wikitext('s')
end
header:wikitext(':')
end
local container = nav:tag('div')
container:addClass(sandboxVersion('portal-bar-content'))
if related then
container:addClass(sandboxVersion('portal-bar-content-related'))
end
local size = related and '27x25px' or '21x19px'
for _, portal in ipairs( portals ) do
container
:tag( 'span' )
:addClass(sandboxVersion('portal-bar-item'))
:wikitext( string.format('[[File:%s|%s]] [[Portal:%s|%s]]',
getImageName(portal,true), size, portal, portal))
end
local styleFile = 'Module:Portal bar'..sandbox..'/styles.css'
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = styleFile }
} .. tostring( nav )
end
-- Processes external arguments and sends them to the other functions.
function p.main( frame )
local origArgs = getArgs(frame)
local portals, args = processPortalArgs(origArgs)
return p._main( portals, args )
end
return p
bb586a960cb56daaef2c7b7c994afbbd94772bbd
Module:Portal bar/styles.css
828
119
254
253
2022-09-04T15:25:04Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp|small=y}} */
.portal-bar {
font-size: 88%;
font-weight: bold;
display:flex;
justify-content: center;
align-items: baseline;
}
.portal-bar-bordered {
padding: 0 2em;
background-color: #fdfdfd;
border: 1px solid #a2a9b1;
clear: both;
margin: 1em auto 0;
}
.portal-bar-related {
font-size: 100%;
justify-content: flex-start;
}
.portal-bar-unbordered {
padding: 0 1.7em;
margin-left: 0;
}
.portal-bar-header {
margin: 0 1em 0 0.5em;
flex: 0 0 auto;
min-height: 24px;
}
.portal-bar-content {
display:flex;
flex-flow: row wrap;
flex:0 1 auto;
padding: 0.15em 0;
column-gap: 1em;
align-items: baseline;
}
.portal-bar-content-related {
}
.portal-bar-item {
display:inline-block;
margin:0.15em 0.2em;
min-height:24px;
line-height:24px;
}
@media screen and (max-width:768px) {
.portal-bar {
font-size: 88%;
font-weight: bold;
display:flex;
flex-flow: column wrap;
align-items: baseline;
}
.portal-bar-header {
text-align: center;
flex:0;
padding-left: 0.5em;
margin: 0 auto;
}
.portal-bar-related {
font-size: 100%;
align-items: flex-start;
}
.portal-bar-content {
display:flex;
flex-flow: row wrap;
align-items: center;
flex:0;
column-gap: 1em;
border-top: 1px solid #a2a9b1;
margin: 0 auto;
}
.portal-bar-content-related {
border-top: none;
margin: 0;
}
}
/* .navbox + .portal-bar-bordered */
.navbox + link + .portal-bar-bordered {
margin-top: -1px;
}
.navbox + style + .portal-bar-bordered {
margin-top: -1px;
}
.portal-bar + .navbox-styles + .navbox{
margin-top: -1px;
}
ec6e77726e7d76d00d66cefce85c3e7d2006d3c5
Template:Trim
10
120
256
255
2022-09-04T15:25:04Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{safesubst:#if:1|{{{x|{{{1|}}}}}}}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
09ba1a40d9fd41a44a407b144f69a579502fe563
Template:Portal bar
10
121
258
257
2022-09-04T15:25:05Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:Portal bar|main}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
147fd2e53f15534b497d1049a4ea239049ec8fbc
Module:Portal/images/aliases
828
122
260
259
2022-09-04T15:25:05Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[==[ This is the "aliases" list of portal image names. It contains a list of portal image aliases for use with [[Module:Portal]].
-- The aliases can be used to point to an existing portal image entry. For portals who do not yet have a portal image entry, please
-- use the appropriate page from the following list instead:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/o]] - for portal names beginning with "O".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- When adding entries, please use alphabetical order. The format of the alias table entries is as follows:
-- ["portal name"] = {"alias 1", "alias 2", "alias 3"},
-- Both the portal name and the alias names should be in lower case, and the "Portal:" namespace prefix
-- should be omitted. For example, if you wanted "UK" to be an alias for "Portal:United Kingdom", then the
-- alias name would be "uk" and the portal name would be "united kingdom".
]==]
return {
["1990s"] = {"1990's"},
["2000s"] = {"2000's"},
["ac/dc"] = {"ac dc"},
["academy award"] = {"academy awards"},
["african american"] = {"african-american", "african-americans", "african americans"},
["african union"] = {"au"},
["agriculture and agronomy"] = {"agriculture"},
["american civil war"] = {"acw"},
["american revolutionary war"] = {"american revolution"},
["amphibians"] = {"amphibian"},
["aviation"] = {"airplanes"},
["åland"] = {"åland islands", "aland islands", "aland", "ax", "ala"},
["albania"] = {"albanian", "al", "alb"},
["american football"] = {"college football", "arena football league"},
["android (operating system)"] = {"android", "android os"},
["apple inc."] = {"apple", "apple inc"},
["arabic language"] = {"arabic"},
["archaeology"] = {"archeology"},
["asian americans"] = {"asian american"},
["association football"] = {"soccer"},
["assyrians"] = {"assyria"},
["atlas"] = {"cartography"},
["atmospheric science"] = {"atmosphere","atmospheric sciences"},
["australia"] = {"australian", "aus"},
["australian capital territory"] = {"canberra"},
["banks"] = {"bank", "banking"},
["baseball"] = {"college baseball", "little league"},
["basketball"] = {"national basketball league of canada", "wnba"},
["biography"] = {"people", "biographies"},
["birds"] = {"bird"},
["björk"] = {"bjork"},
["books"] = {"book"},
["brunei"] = {"brunei darussalam", "bn", "brn"},
["business and economics"] = {"advertising", "business", "economics", "economy", "marketing"},
["buses"] = {"bus"},
["california roads"] = {"roads in california"},
["california state polytechnic university, pomona"] = {"cal poly pomona"},
["canada"] = {"canadian", "ca", "can"},
["canadian armed forces"] = {"canadian forces", "military history of canada"},
["canary islands"] = {"spanish africa"},
["caribbean"] = {"caribbean sea", "west indies"},
["cars"] = {"car", "automobile"},
["cartoon"] = {"cartoons"},
["catalan-speaking countries"] = {"catalan", "catalonia"},
["cats"] = {"cat"},
["celtic studies"] = {"celts"},
["children's literature"] = {"children's and young adult literature", "children and young adult literature"},
["china"] = {"chinese", "cn", "chn"},
["christiantiy"] = {"christ", "christian"},
["christianity in india"] = {"indian christianity"},
["classical civilisation"] = {"classical civilization", "classics"},
["cleveland"] = {"cleveland, ohio"},
["coconuts"] = {"coconut"},
["color"] = {"colour"},
["comedy"] = {"humour", "humor"},
["commonwealth realms"] = {"commonwealth"},
["compact disc"] = {"cd", "compact disk"},
["companies"] = {"company"},
["computer-generated imagery"] = {"computer generated imagery"},
["computer programming"] = {"programming"},
["county kilkenny"] = {"kilkenny"},
["criminal justice"] = {"crime"},
["current events"] = {"events"},
["czech republic"] = {"czechia", "czech"},
["dallas – fort worth metroplex"] = {"dallas", "dallas-fort worth", "dallas - fort worth metroplex"},
["democratic republic of the congo"] = {"zaire", "zaïre", "cod", "drc", "the democratic republic of the congo"},
["denmark"] = {"kingdom of denmark", "danish", "dk", "dnk"},
["disasters"] = {"disaster"},
["dravidian languages"] = {"dravidian", "dravidia", "dravidian peoples", "dravidian civilization"},
["dominican republic"] = {"the dominican republic"},
["durham, north carolina"] = {"durham nc"},
["dungeons & dragons"] = {"d&d"},
["east timor"] = {"timor leste", "tl"},
["electromagnetism"] = {"em"},
["english football"] = {"football in england"},
["english language"] = {"english"},
["erotica and pornography"] = {"porn", "pornography"},
["european military history"] = {"military history of europe"},
["european union"] = {"eu"},
["evolutionary biology"] = {"evolution"},
["extinct and endangered species"] = {"extinction", "endangered species"},
["falkland islands"] = {"falkland", "malvinas", "fk", "flk"},
["faroe islands"] = {"the faroe islands"},
["federated states of micronesia"] = {"fm", "fsm"},
["film"] = {"films"},
["football"] = {"association football", "soccer", "soccer ball"},
["formula one"] = {"f1", "formula 1"},
["free and open-source software"] = {"free and open source software", "free software", "foss", "open source software", "open-source software", "oss"},
["freedom of speech"] = {"censorship", "free speech"},
["french and francophone literature"] = {"french literature"},
["french politics"] = {"politics of france"},
["gardening"] = {"gardening and horticulture"},
["gemology and jewelry"] = {"gemmology and jewellery", "gemmology and jewelry", "gemology and jewellery"},
["georgia (country)"] = {"georgia", "republic of georgia", "ge", "geo"},
["georgia (u.s. state)"] = {"georgia (state)"},
["globalization"] = {"globalisation"},
["gullah"] = {"gullah people"},
["hawaii"] = {"hawai'i", "hawaiʻi", "us-hi"},
["hazardous materials"] = {"dangerous goods"},
["health and fitness"] = {"health"},
["himalayas"] = {"himalaya region"},
["hindustani"] = {"hindustani language", "hindustani and allied languages"},
["hip hop"] = {"hip-hop"},
["hispanic and latino americans"] = {"hispanic and latino american", "latino and hispanic americans", "latino and hispanic american"},
["horror fiction"] = {"horror"},
["horticulture and gardening"] = {"horticulture"},
["hunger relief"] = {"hunger"},
["india"] = {"indian", "in", "ind", "republic of india"},
["indian women"] = {"women of india", "indian women and gender issues"},
["indiana"] = {"hoosier", "us-in"},
["indigenous peoples of north america"] = {"indigenous people of north america"},
["information technology"] = {"computing", "computer science", "it"},
["insects"] = {"insect"},
["ireland"] = {"irish"},
["islam"] = {"muslim history"},
["islamic state of iraq and the levant"] = {"daesh", "isil", "isis"},
["islands"] = {"island"},
["italy"] = {"italian", "ita"},
["jacksonville, florida"] = {"jacksonville"},
["kazi nazrul islam"] = {"nazrul"},
["latter day saint movement"] = {"lds"},
["lemony snicket"] = {"a series of unfortunate events"},
["lgbt"] = {"lgbtq", "lgbtqa"},
["library and information science"] = {"information science"},
["madonna (entertainer)"] = {"madonna"},
["mediterranean"] = {"mediterranean sea"},
["metro detroit"] = {"detroit"},
["mexico"] = {"méxico", "mx", "mex"},
["middle tennessee state university"] = {"mtsu"},
["michigan highways"] = {"highways in michigan"},
["molecular and cell biology"] = {"molecular and cellular biology"},
["moldova"] = {"republic of moldova"},
["mongolia"] = {"mongols"},
["mountains"] = {"mountain"},
["music of australia"] = {"australian music"},
["myanmar"] = {"burma", "burmese", "mm", "mmr"},
["national register of historic places"] = {"nrhp"},
["nazism"] = {"nazi germany"},
["netherlands"] = {"kingdom of the netherlands", "nl", 'nld', 'caribbean netherlands', 'the netherlands', 'dutch empire', 'the dutch empire'},
["new york"] = {"new york state", "new york (state)", "us-ny"},
["new york city"] = {"nyc"},
["new zealand"] = {"nz", "nzl"},
["north korea"] = {"dprk", "democratic people's republic of korea"},
["north macedonia"] = {"republic of north macedonia", "mk", "mkd"},
["north rhine-westphalia"] = {"nrw"},
["oceans"] = {"ocean", "world ocean"},
["odisha"] = {"orissa"},
["opera"] = {"operas"},
["organized labour"] = {"organised labour", "organized labor"},
["pakistan"] = {"pakistani", "pk", "pak"},
["paleontology"] = {"palaeontology"},
["palestine"] = {"the state of palestine","state of palestine"},
["paralympic games"] = {"paralympics"},
["pan-africanism"] = {"pan-african"},
["people's republic of china"] = {"prc"},
["pharmacy and pharmacology"] = {"pharmacy"},
["pitcairn islands"] = {"pitcairn, henderson, ducie and oeno islands"},
["politics"] = {"government"},
["prince edward island"] = {"pei", "ca-pe"},
["protected areas of india"] = {"biodiversity, protected areas & environment of india", "biodiversity of india", "environment of india"},
["puducherry"] = {"pondicherry", "in-py"},
["punjab, india"] = {"punjab (india)", "in-pb"},
["punjab, pakistan"] = {"punjab (pakistan)", "western punjab", "pk-pb"},
["python programming"] = {"python"},
["quebec"] = {"québec", "ca-qc"},
["religion"] = {"religions"},
["republic of ireland"] = {"éire", "ie", "irl", "irish republicanism"},
["republic of north macedonia"] = {"north macedonia", "mk", "mkd", "the republic of macedonia", "republic of macedonia"},
["republic of the congo"] = {"the republic of the congo", "republic of congo", "french congo"},
["roads of canada"] = {"canada roads"},
["romani people"] = {"roma", "romani"},
["saint barthelemy"] = {"saint-barthélemy", "saint barthélemy"},
["saint helena, ascension and tristan da cunha"] = {"saint helena"},
["salad dressing"] = {"salad dressings"},
["sandwich"] = {"sandwiches"},
["schools"] = {"school"},
["serer people"] = {"serer"},
["september 11 attacks"] = {"september 11, 2001"},
["sexuality"] = {"sex"},
["soap operas and telenovelas"] = {"soap operas", "telenovelas"},
["south africa"] = {"za", "zaf"},
["south georgia and the south sandwich islands"] = {"south georgia", "south sandwich islands", "gs", "sgs"},
["soviet union"] = {"ussr"},
["space"] = {"outer space"},
["spices"] = {"herbs and spices"},
["sports in canada"] = {"canadian sports", "canadian sport", "sports of canada", "sport in canada"},
["sports"] = {"sport"},
["st. john's, newfoundland and labrador"] = {"st. john's"},
["state of georgia"] = {"georgia (u.s. state)", "georgia usa", "us-ga"},
["state of mexico"] = {"mexico (state)", "mx-mex"},
["state university of new york"] = {"suny"},
["taiwan"] = {"republic of china", "roc", "tw", "twn"},
["tamil people"] = {"tamil"},
["tanks"] = {"tank"},
["telecommunication"] = {"telecommunications", "telecoms", "telecomms", "telecomm", "telecom"},
["texas a&m university"] = {"texas a&m"},
["texas tech university"] = {"texas tech"},
["theatre"] = {"theater"},
["the bahamas"] = {"bahamas", "bs", "bhs"},
["the gambia"] = {"gambia", "gm", "gmb"},
["the legend of zelda"] = {"legend of zelda"},
["tiruchirappalli"] = {"trichy", "tiruchi"},
["transportation"] = {"transport"},
["trauma and orthopaedics"] = {"trauma & orthopaedics"},
["tropical cyclones"] = {"tropical cyclone"},
["united arab emirates"] = {"emirates", "ae", "uae", "emirati"},
["united kingdom"] = {"the united kingdom", "uk", "gb", "gbr", "british", "british overseas territories"},
["united nations"] = {"un"},
["united states"] = {"us", "usa", "u.s.", "united states armed forces", "american", "territories of the united states"},
["united states arms"] = {"united states armed forces", "united states military", "united states military history", "u.s. armed forces", "u.s. military"},
["united states congress"] = {"u.s. congress"},
["united states counties"] = {"u.s. counties"},
["united states presidents"] = {"u.s. presidents"},
["united states roads"] = {"u.s. roads"},
["united states state legislatures"] = {"u.s. state legislatures", "us state legislatures"},
["united states streets"] = {"u.s. streets"},
["united states supreme court"] = {"u.s. supreme court cases"},
["united states territories"] = {"territories of the united states"},
["university of missouri"] = {"mizzou"},
["university of notre dame"] = {"notre dame"},
["university of pittsburgh"] = {"pitt"},
["video games"] = {"vg", "video game"},
["war"] = {"military"},
["washington (state)"] = {"washington", "us-wa"},
["washington, d.c."] = {"district of columbia", "dc", "washington dc", "us-dc"},
["western asia"] = {"west asia"},
["western sahara"] = {"sahrawi arab democratic republic", "eh", "esh"},
["world war i"] = {"first world war"},
["world war ii"] = {"second world war"},
["zoos"] = {"zoo"}
}
06ad5a8008671463b8305eb44bb61afb68f4f1df
Template:Comma separated entries
10
123
262
261
2022-09-04T15:25:05Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|comma}}<noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
f9811ed089bab742e4aad8b8463eddcc7607f062
Template:Citation
10
124
264
263
2022-09-04T15:25:06Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=citation
}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
682134a60c143dec260ce779777d3be2d4c94eaa
Module:Template wrapper
828
125
266
265
2022-09-04T15:25:06Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require('Module:No globals');
local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">|_template=</code> missing or empty</span>';
--[[--------------------------< I S _ I N _ T A B L E >--------------------------------------------------------
scan through tbl looking for value; return true if found, false else
]]
local function is_in_table (tbl, value)
for k, v in pairs (tbl) do
if v == value then return true end
end
return false;
end
--[[--------------------------< A D D _ P A R A M E T E R >----------------------------------------------------
adds parameter name and its value to args table according to the state of boolean list argument; kv pair for
template execution; k=v string for template listing.
]]
local function add_parameter (k, v, args, list)
if list then
table.insert( args, table.concat ({k, '=', v})); -- write parameter names and values to args table as string
else
args[k] = v; -- copy parameters to args table
end
end
--[[--------------------------< A L I A S _ M A P _ G E T >----------------------------------------------------
returns a table of local template (parent frame) parameter names and the target template names that match where
in [key]=<value> pairs where:
[key] is local template parameter name (an alias)
<value> is target template parameter name (the canonical parameter name used in the working template)
The parameter |_alias-map= has the form:
|_alias-map=<list>
where <list> is a comma-separated list of alias / canonical parameter name pairs in the form
<from> : <to>
where:
<from> is the local template's parameter name (alias)
<to> is the target template's parameter name (canonical)
for enumerated parameters place an octothorp (#) where the enumerator digits are placed in the parameter names:
<from#> : <to#>
]]
local function alias_map_get (_alias_map)
local T = mw.text.split (_alias_map, '%s*,%s*'); -- convert the comma-separated list into a table of alias pairs
local mapped_aliases = {}; -- mapped aliases will go here
local l_name, t_name; -- parameter names
for _, alias_pair in ipairs (T) do -- loop through the table of alias pairs
l_name, t_name = alias_pair:match ('(.-)%s*:%s*(.+)'); -- from each pair, get local and target parameter names
if l_name and t_name then -- if both are set
if tonumber (l_name) then
l_name = tonumber (l_name); -- convert number-as-text to a number
end
mapped_aliases[l_name] = t_name; -- add them to the map table
end
end
return mapped_aliases;
end
--[[--------------------------< F R A M E _ A R G S _ G E T >--------------------------------------------------
Fetch the wrapper template's 'default' and control parameters; adds default parameters to args
returns content of |_template= parameter (name of the working template); nil else
]]
local function frame_args_get (frame_args, args, list)
local template;
for k, v in pairs (frame_args) do -- here we get the wrapper template's 'default' parameters
if 'string' == type (k) and (v and ('' ~= v)) then -- do not pass along positional or empty parameters
if '_template' == k then
template = v; -- save the name of template that we are wrapping
elseif '_exclude' ~= k and '_reuse' ~= k and '_include-positional' ~= k and '_alias-map' ~= k then -- these already handled so ignore here;
add_parameter (k, v, args, list); -- add all other parameters to args in the style dictated by list
end
end
end
return template; -- return contents of |_template= parameter
end
--[=[--------------------------< P F R A M E _ A R G S _ G E T >------------------------------------------------
Fetches the wrapper template's 'live' parameters; adds live parameters that aren't members of the exclude table to
args table; positional parameters may not be excluded
no return value
]=]
local function pframe_args_get (pframe_args, args, exclude, _include_positional, list)
for k, v in pairs (pframe_args) do
if 'string' == type (k) and not is_in_table (exclude, k) then -- do not pass along excluded parameters
if v and ('' ~= v) then -- pass along only those parameters that have assigned values
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (k, v, args, list) -- add all other parameters to args in the style dictated by list; alias map only supported for local-template parameters
end
end
end
if _include_positional then
for i, v in ipairs (pframe_args) do -- pass along positional parameters
if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template
v = ''; -- unset the value in the args table
end
add_parameter (i, v, args, list);
end
end
end
--[[--------------------------< _ M A I N >--------------------------------------------------------------------
Collect the various default and live parameters into args styled according to boolean list.
returns name of the working or listed template or nil for an error message
]]
local function _main (frame, args, list)
local template;
local exclude = {}; -- table of parameter names for parameters that are not passed to the working template
local reuse_list = {}; -- table of pframe parameter names whose values are modified before they are passed to the working template as the same name
local alias_map = {}; -- table that maps parameter aliases to working template canonical parameter names
local _include_positional;
if frame.args._exclude and ('' ~= frame.args._exclude) then -- if there is |_exclude= and it's not empty
exclude = mw.text.split (frame.args._exclude, "%s*,%s*"); -- make a table from its contents
end
-- TODO: |_reuse= needs a better name (|_reuse=)
if frame.args._reuse and ('' ~= frame.args._reuse) then -- if there is |_reuse= and it's not empty
reuse_list = mw.text.split (frame.args._reuse, "%s*,%s*"); -- make a table from its contents
end
if frame.args['_alias-map'] and ('' ~= frame.args['_alias-map']) then -- if there is |_alias-map= and it's not empty
alias_map = alias_map_get (frame.args['_alias-map']); -- make a table from its contents
end
template = frame_args_get (frame.args, args, list); -- get parameters provided in the {{#invoke:template wrapper|...|...}}
if nil == template or '' == template then -- this is the one parameter that is required by this module
return nil; -- not present, tell calling function to emit an error message
end
_include_positional = 'yes' == frame.args['_include-positional']; -- when true pass all positional parameters along with non-excluded named parameters to ...
-- ... the working template; positional parameters are not excludable
local _pframe_args = frame:getParent().args; -- here we get the wrapper template's 'live' parameters from pframe.args
local pframe_args = {}; -- a local table that we can modify
for k, v in pairs (_pframe_args) do -- make a copy that we can modify
pframe_args[k] = v;
end
-- here we look for pframe parameters that are aliases of canonical parameter names; when found
-- we replace the alias with the canonical. We do this here because the reuse_list works on
-- canonical parameter names so first we convert alias parameter names to canonical names and then
-- we remove those canonical names from the pframe table that are reused (provided to the working
-- template through the frame args table)
for k, v in pairs (alias_map) do -- k is alias name, v is canonical name
if pframe_args[k] then -- if pframe_args has parameter with alias name
pframe_args[v] = _pframe_args[k]; -- create new canonical name with alias' value
pframe_args[k] = nil; -- unset the alias
end
end
for k, v in pairs (pframe_args) do -- do enumerated parameter alias -> canonical translation
if 'string' == type (k) then -- only named parameters can be enumerated
if alias_map[k..'#'] then -- non-enumerated alias matches enumerated parameter pattern? enumerator at end only
pframe_args[alias_map[k..'#']:gsub('#', '')] = v; -- remove '#' and copy parameter to pframe_args table
pframe_args[k] = nil; -- unset the alias
elseif k:match ('%d+') then -- if this parameter name contains digits
local temp = k:gsub ('%d+', '#'); -- make a copy; digits replaced with single '#'
local enum = k:match ('%d+'); -- get the enumerator
if alias_map[temp] then -- if this parameter is a recognized enumerated alias
pframe_args[alias_map[temp]:gsub('#', enum)] = v; -- use canonical name and replace '#' with enumerator and add to pframe_args
pframe_args[k] = nil; -- unset the alias
end
end
end
end
-- pframe parameters that are _reused are 'reused' have the form something like this:
-- |chapter=[[wikisource:{{{chapter}}}|{{{chapter}}}]]
-- where a parameter in the wrapping template is modified and then passed to the working template
-- using the same parameter name (in this example |chapter=)
-- remove parameters that will be reused
for k, v in ipairs (reuse_list) do -- k is numerical index, v is canonical parameter name to ignore
if pframe_args[v] then -- if pframe_args has parameter that should be ignored
pframe_args[v] = nil; -- unset the ignored parameter
end
end
pframe_args_get (pframe_args, args, exclude, _include_positional, list); -- add parameters and values to args that are not listed in the exclude table
return template; -- args now has all default and live parameters, return working template name
end
--[[--------------------------< W R A P >----------------------------------------------------------------------
Template entry point. Call this function to 'execute' the working template
]]
local function wrap (frame)
local args = {}; -- table of default and live parameters and their values to be passed to the wrapped template
local template; -- the name of the working template
template = _main (frame, args, false); -- get default and live parameters and the name of the working template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
return frame:expandTemplate {title=template, args=args}; -- render the working template
end
--[[--------------------------< L I S T >----------------------------------------------------------------------
Template entry point. Call this function to 'display' the source for the working template. This function added
as a result of a TfD here: Wikipedia:Templates_for_discussion/Log/2018_April_28#Module:PassArguments
This function replaces a similarly named function which was used in {{cite compare}} and {{cite compare2}}
Values in the args table are numerically indexed strings in the form 'name=value'
]]
local function list(frame, do_link)
local args = {}; -- table of default and live parameters and their values to be passed to the listed template
local template; -- the name of the listed template
template = _main (frame, args, true); -- get default and live parameters and the name of the listed template
if not template then -- template name is required
return error_msg; -- emit error message and abandon if template name not present
end
if do_link then
template = ('[[%s|%s]]'):format(frame:expandTemplate{ title='Transclude', args = {template} }, template)
end
table.sort(args)
for i = 1, #args do
local stripped = args[i]:match('^' .. i .. '=([^=]*)$')
if stripped then args[i] = stripped else break end
end
return frame:preprocess(table.concat({
'<code style="color:inherit; background:inherit; border:none;">{{',
template,
('<wbr><nowiki>|%s</nowiki>'):rep(#args):format(unpack(args)), '}}</code>'})); -- render the template
end
local function link (frame)
return list(frame, true)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
link = link,
list = list,
wrap = wrap,
};
aa1b56cac4081642637ea7d11fba53513d4335a7
Template:Round
10
126
268
267
2022-09-04T15:25:06Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{safesubst<noinclude/>:#iferror:{{#expr:{{{2|0}}}}} |
{{main other|[[Category:Pages with bad rounding precision]]}}{{hid|Bad rounding here}}<!--
-->{{safesubst<noinclude/>:#invoke:Math|precision_format| {{{1}}} | 1-{{order of magnitude|{{{1}}}}} }}|
{{safesubst<noinclude/>:#invoke:Math|precision_format| {{{1}}} | {{{2|0}}}}}}}</includeonly><noinclude>
{{documentation}}
</noinclude>
9c2874586b74824fe1beb6830b56eabe7ad936ce
Module:Math
828
127
270
269
2022-09-04T15:25:07Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[[
This module provides a number of basic mathematical operations.
]]
local yesno, getArgs -- lazily initialized
local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules.
local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.
--[[
Helper functions used to avoid redundant code.
]]
local function err(msg)
-- Generates wikitext error messages.
return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg)
end
local function unpackNumberArgs(args)
-- Returns an unpacked list of arguments specified with numerical keys.
local ret = {}
for k, v in pairs(args) do
if type(k) == 'number' then
table.insert(ret, v)
end
end
return unpack(ret)
end
local function makeArgArray(...)
-- Makes an array of arguments from a list of arguments that might include nils.
local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs.
local nums = {} -- Stores the numbers of valid numerical arguments.
local ret = {}
for k, v in pairs(args) do
v = p._cleanNumber(v)
if v then
nums[#nums + 1] = k
args[k] = v
end
end
table.sort(nums)
for i, num in ipairs(nums) do
ret[#ret + 1] = args[num]
end
return ret
end
local function fold(func, ...)
-- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters,
-- and must return a number as an output. This number is then supplied as input to the next function call.
local vals = makeArgArray(...)
local count = #vals -- The number of valid arguments
if count == 0 then return
-- Exit if we have no valid args, otherwise removing the first arg would cause an error.
nil, 0
end
local ret = table.remove(vals, 1)
for _, val in ipairs(vals) do
ret = func(ret, val)
end
return ret, count
end
--[[
Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value).
]]
local function binary_fold(func, ...)
local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...)
return value
end
--[[
random
Generate a random number
Usage:
{{#invoke: Math | random }}
{{#invoke: Math | random | maximum value }}
{{#invoke: Math | random | minimum value | maximum value }}
]]
function wrap.random(args)
local first = p._cleanNumber(args[1])
local second = p._cleanNumber(args[2])
return p._random(first, second)
end
function p._random(first, second)
math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000))
-- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params.
if first and second then
if first <= second then -- math.random doesn't allow the first number to be greater than the second.
return math.random(first, second)
end
elseif first then
return math.random(first)
else
return math.random()
end
end
--[[
order
Determine order of magnitude of a number
Usage:
{{#invoke: Math | order | value }}
]]
function wrap.order(args)
local input_string = (args[1] or args.x or '0');
local input_number = p._cleanNumber(input_string);
if input_number == nil then
return err('order of magnitude input appears non-numeric')
else
return p._order(input_number)
end
end
function p._order(x)
if x == 0 then return 0 end
return math.floor(math.log10(math.abs(x)))
end
--[[
precision
Detemines the precision of a number using the string representation
Usage:
{{ #invoke: Math | precision | value }}
]]
function wrap.precision(args)
local input_string = (args[1] or args.x or '0');
local trap_fraction = args.check_fraction;
local input_number;
if not yesno then
yesno = require('Module:Yesno')
end
if yesno(trap_fraction, true) then -- Returns true for all input except nil, false, "no", "n", "0" and a few others. See [[Module:Yesno]].
local pos = string.find(input_string, '/', 1, true);
if pos ~= nil then
if string.find(input_string, '/', pos + 1, true) == nil then
local denominator = string.sub(input_string, pos+1, -1);
local denom_value = tonumber(denominator);
if denom_value ~= nil then
return math.log10(denom_value);
end
end
end
end
input_number, input_string = p._cleanNumber(input_string);
if input_string == nil then
return err('precision input appears non-numeric')
else
return p._precision(input_string)
end
end
function p._precision(x)
if type(x) == 'number' then
x = tostring(x)
end
x = string.upper(x)
local decimal = x:find('%.')
local exponent_pos = x:find('E')
local result = 0;
if exponent_pos ~= nil then
local exponent = string.sub(x, exponent_pos + 1)
x = string.sub(x, 1, exponent_pos - 1)
result = result - tonumber(exponent)
end
if decimal ~= nil then
result = result + string.len(x) - decimal
return result
end
local pos = string.len(x);
while x:byte(pos) == string.byte('0') do
pos = pos - 1
result = result - 1
if pos <= 0 then
return 0
end
end
return result
end
--[[
max
Finds the maximum argument
Usage:
{{#invoke:Math| max | value1 | value2 | ... }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.max(args)
return p._max(unpackNumberArgs(args))
end
function p._max(...)
local max_value = binary_fold((function(a, b) return a > b end), ...)
if max_value then
return max_value
end
end
--[[
median
Find the median of set of numbers
Usage:
{{#invoke:Math | median | number1 | number2 | ...}}
OR
{{#invoke:Math | median }}
]]
function wrap.median(args)
return p._median(unpackNumberArgs(args))
end
function p._median(...)
local vals = makeArgArray(...)
local count = #vals
table.sort(vals)
if count == 0 then
return 0
end
if p._mod(count, 2) == 0 then
return (vals[count/2] + vals[count/2+1])/2
else
return vals[math.ceil(count/2)]
end
end
--[[
min
Finds the minimum argument
Usage:
{{#invoke:Math| min | value1 | value2 | ... }}
OR
{{#invoke:Math| min }}
When used with no arguments, it takes its input from the parent
frame. Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.min(args)
return p._min(unpackNumberArgs(args))
end
function p._min(...)
local min_value = binary_fold((function(a, b) return a < b end), ...)
if min_value then
return min_value
end
end
--[[
sum
Finds the sum
Usage:
{{#invoke:Math| sum | value1 | value2 | ... }}
OR
{{#invoke:Math| sum }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.sum(args)
return p._sum(unpackNumberArgs(args))
end
function p._sum(...)
local sums, count = fold((function(a, b) return a + b end), ...)
if not sums then
return 0
else
return sums
end
end
--[[
average
Finds the average
Usage:
{{#invoke:Math| average | value1 | value2 | ... }}
OR
{{#invoke:Math| average }}
Note, any values that do not evaluate to numbers are ignored.
]]
function wrap.average(args)
return p._average(unpackNumberArgs(args))
end
function p._average(...)
local sum, count = fold((function(a, b) return a + b end), ...)
if not sum then
return 0
else
return sum / count
end
end
--[[
round
Rounds a number to specified precision
Usage:
{{#invoke:Math | round | value | precision }}
--]]
function wrap.round(args)
local value = p._cleanNumber(args[1] or args.value or 0)
local precision = p._cleanNumber(args[2] or args.precision or 0)
if value == nil or precision == nil then
return err('round input appears non-numeric')
else
return p._round(value, precision)
end
end
function p._round(value, precision)
local rescale = math.pow(10, precision or 0);
return math.floor(value * rescale + 0.5) / rescale;
end
--[[
log10
returns the log (base 10) of a number
Usage:
{{#invoke:Math | log10 | x }}
]]
function wrap.log10(args)
return math.log10(args[1])
end
--[[
mod
Implements the modulo operator
Usage:
{{#invoke:Math | mod | x | y }}
--]]
function wrap.mod(args)
local x = p._cleanNumber(args[1])
local y = p._cleanNumber(args[2])
if not x then
return err('first argument to mod appears non-numeric')
elseif not y then
return err('second argument to mod appears non-numeric')
else
return p._mod(x, y)
end
end
function p._mod(x, y)
local ret = x % y
if not (0 <= ret and ret < y) then
ret = 0
end
return ret
end
--[[
gcd
Calculates the greatest common divisor of multiple numbers
Usage:
{{#invoke:Math | gcd | value 1 | value 2 | value 3 | ... }}
--]]
function wrap.gcd(args)
return p._gcd(unpackNumberArgs(args))
end
function p._gcd(...)
local function findGcd(a, b)
local r = b
local oldr = a
while r ~= 0 do
local quotient = math.floor(oldr / r)
oldr, r = r, oldr - quotient * r
end
if oldr < 0 then
oldr = oldr * -1
end
return oldr
end
local result, count = fold(findGcd, ...)
return result
end
--[[
precision_format
Rounds a number to the specified precision and formats according to rules
originally used for {{template:Rnd}}. Output is a string.
Usage:
{{#invoke: Math | precision_format | number | precision }}
]]
function wrap.precision_format(args)
local value_string = args[1] or 0
local precision = args[2] or 0
return p._precision_format(value_string, precision)
end
function p._precision_format(value_string, precision)
-- For access to Mediawiki built-in formatter.
local lang = mw.getContentLanguage();
local value
value, value_string = p._cleanNumber(value_string)
precision = p._cleanNumber(precision)
-- Check for non-numeric input
if value == nil or precision == nil then
return err('invalid input when rounding')
end
local current_precision = p._precision(value)
local order = p._order(value)
-- Due to round-off effects it is neccesary to limit the returned precision under
-- some circumstances because the terminal digits will be inaccurately reported.
if order + precision >= 14 then
if order + p._precision(value_string) >= 14 then
precision = 13 - order;
end
end
-- If rounding off, truncate extra digits
if precision < current_precision then
value = p._round(value, precision)
current_precision = p._precision(value)
end
local formatted_num = lang:formatNum(math.abs(value))
local sign
-- Use proper unary minus sign rather than ASCII default
if value < 0 then
sign = '−'
else
sign = ''
end
-- Handle cases requiring scientific notation
if string.find(formatted_num, 'E', 1, true) ~= nil or math.abs(order) >= 9 then
value = value * math.pow(10, -order)
current_precision = current_precision + order
precision = precision + order
formatted_num = lang:formatNum(math.abs(value))
else
order = 0;
end
formatted_num = sign .. formatted_num
-- Pad with zeros, if needed
if current_precision < precision then
local padding
if current_precision <= 0 then
if precision > 0 then
local zero_sep = lang:formatNum(1.1)
formatted_num = formatted_num .. zero_sep:sub(2,2)
padding = precision
if padding > 20 then
padding = 20
end
formatted_num = formatted_num .. string.rep('0', padding)
end
else
padding = precision - current_precision
if padding > 20 then
padding = 20
end
formatted_num = formatted_num .. string.rep('0', padding)
end
end
-- Add exponential notation, if necessary.
if order ~= 0 then
-- Use proper unary minus sign rather than ASCII default
if order < 0 then
order = '−' .. lang:formatNum(math.abs(order))
else
order = lang:formatNum(order)
end
formatted_num = formatted_num .. '<span style="margin:0 .15em 0 .25em">×</span>10<sup>' .. order .. '</sup>'
end
return formatted_num
end
--[[
divide
Implements the division operator
Usage:
{{#invoke:Math | divide | x | y | round= | precision= }}
--]]
function wrap.divide(args)
local x = args[1]
local y = args[2]
local round = args.round
local precision = args.precision
if not yesno then
yesno = require('Module:Yesno')
end
return p._divide(x, y, yesno(round), precision)
end
function p._divide(x, y, round, precision)
if y == nil or y == "" then
return err("Empty divisor")
elseif not tonumber(y) then
if type(y) == 'string' and string.sub(y, 1, 1) == '<' then
return y
else
return err("Not a number: " .. y)
end
elseif x == nil or x == "" then
return err("Empty dividend")
elseif not tonumber(x) then
if type(x) == 'string' and string.sub(x, 1, 1) == '<' then
return x
else
return err("Not a number: " .. x)
end
else
local z = x / y
if round then
return p._round(z, 0)
elseif precision then
return p._round(z, precision)
else
return z
end
end
end
--[[
Helper function that interprets the input numerically. If the
input does not appear to be a number, attempts evaluating it as
a parser functions expression.
]]
function p._cleanNumber(number_string)
if type(number_string) == 'number' then
-- We were passed a number, so we don't need to do any processing.
return number_string, tostring(number_string)
elseif type(number_string) ~= 'string' or not number_string:find('%S') then
-- We were passed a non-string or a blank string, so exit.
return nil, nil;
end
-- Attempt basic conversion
local number = tonumber(number_string)
-- If failed, attempt to evaluate input as an expression
if number == nil then
local success, result = pcall(mw.ext.ParserFunctions.expr, number_string)
if success then
number = tonumber(result)
number_string = tostring(number)
else
number = nil
number_string = nil
end
else
number_string = number_string:match("^%s*(.-)%s*$") -- String is valid but may contain padding, clean it.
number_string = number_string:match("^%+(.*)$") or number_string -- Trim any leading + signs.
if number_string:find('^%-?0[xX]') then
-- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead.
number_string = tostring(number)
end
end
return number, number_string
end
--[[
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.
]]
local mt = { __index = function(t, k)
return function(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return wrap[k](getArgs(frame)) -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.
end
end }
return setmetatable(p, mt)
2bbe734d898299f65412963a3c1782e9fcc4d9ca
Template:Sclass
10
128
272
271
2022-09-04T15:25:07Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{sclass/core|1={{{1}}}|2={{{2}}}|3={{{3|}}}|4={{{4|}}}|5={{{5|}}}|format=sclass}}</includeonly><!--
--><noinclude>{{documentation}}</noinclude>
9e6cac27c57200a375f9fd66187d590a922157d2
Template:Sclass/core
10
129
274
273
2022-09-04T15:25:07Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>[[{{{1}}}-class {{{2}}} {{#if:{{{5|}}}|({{{5}}})}}|{{#switch:{{{format}}}
|sclass =''{{{1}}}''
|sclass2 ={{{1}}}
}}<!--
-->{{#switch:{{{3|}}}
|=-class]] [[{{#if:{{{4|}}}|{{{2}}} ({{{4}}}){{!}}{{{2}}}|{{{2}}}}}]]
|0 =-class]]
|1 =-class {{{2}}}]]
|2 =-class]] {{{2}}}
|3 =-class]] [[{{#if:{{{4|}}}|{{{2}}} ({{{4}}}){{!}}{{{2}}}|{{{2}}}}}]]
|4 = class]]
|5 =]]
|6|#default=-class {{{2}}}]]<!-- same as 1, 3; warning + cat
-->{{preview warning|[[Template:{{{format|}}}|Template {{ucfirst:{{{format|}}}}}]], invalid format code: {{{3|}}}. Should be 1–5, or blank.}}{{main other|[[Category:WPSHIPS: sclass invalid option]]}}<!--
-->}}<!-- eo switch
--></includeonly><noinclude>{{documentation}}</noinclude>
d536aa9b427477a08e0d51d8dc68ef00c5c82098
Template:Cite OED
10
130
276
275
2022-09-04T15:25:07Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:template wrapper|{{#if:{{{_debug|}}}|list|wrap}}|_template=cite dictionary
|_exclude=id, short, term, _debug
|url={{#ifeq:{{{term|{{{1|}}}<!-- -->}}}|<!--not set-->|
|{{#if:{{{id|}}}
|https://www.oed.com/view/Entry/{{{id}}}
|https://oed.com/search?searchType=dictionary&q={{urlencode:{{{term|{{{1|}}}}}}}}
}}
}}
|url-access={{#if:{{{term|}}}{{{1|}}}{{{id|}}}|subscription}}
|title={{{term|{{{1|}}}}}}
|dictionary=[[Oxford English Dictionary]]
|publisher={{#if:{{{short|}}}||[[Oxford University Press]]}}
|edition={{#if:{{{short|}}}||Online}}
|ref={{#if:{{{term|}}}{{{1|}}}{{{id|}}}|{{SfnRef|Reference-OED-{{{term|{{{1|}}}}}}}}}}
}}{{#if:{{{short|}}}| | {{OEDsub|sentence={{#ifeq:{{{mode|cs1}}}|cs1|yes|no}}}}<!---->}}<noinclude>
{{documentation}}
</noinclude>
c4826a4de9a2fb0fb19a568c15f96013d914f71d
Template:Cite dictionary
10
131
278
277
2022-09-04T15:25:08Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:Cite encyclopedia]]
b08dc3862c41642a1bb23bc31b3764ffdce55dcc
Template:Link note
10
132
280
279
2022-09-04T15:25:08Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<span style="font-size:0.95em; font-size:95%; color:#555">({{{note|}}})</span><includeonly>{{#if:{{{cat|}}}|{{DMCA|{{{cat|}}}|from|{{{date|}}}}}}}</includeonly><noinclude>{{documentation}}</noinclude>
86089fa5a81775a10f0a53b58426a73b5c9a69ba
Template:OED
10
133
282
281
2022-09-04T15:25:09Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:Cite OED]]
{{R from move}}
d5391a8c7307b290008c46b310b929153eb9440f
Template:OEDsub
10
134
284
283
2022-09-04T15:25:09Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{link note|note={{#ifeq: {{{sentence|no}}} | yes | S | s }}ubscription or [https://www.oed.com/public/login/loggingin#withyourlibrary participating institution membership] required{{#ifeq: {{{sentence|no}}} | yes | . | }}}}<noinclude>
{{Documentation}}
</noinclude>
66a4cfbe3af90f20ac87af655115d9debd61bb56
Template:Cite conference
10
135
286
285
2022-09-04T15:25:09Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:citation/CS1|citation
|CitationClass=conference
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
3c799319c67a4e713f07b5476ef62fa6a9efc608
Module:Portal/images/o
828
136
288
287
2022-09-04T15:25:09Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
--[==[ This is the "O" list of portal image names. It contains a list of portal images for use with [[Module:Portal]]
-- for portal names that start with the letter "O". For aliases to existing portal names, and for portal names that
-- start with other letters, please use the appropriate page from the following list:
-- [[Module:Portal/images/a]] - for portal names beginning with "A".
-- [[Module:Portal/images/b]] - for portal names beginning with "B".
-- [[Module:Portal/images/c]] - for portal names beginning with "C".
-- [[Module:Portal/images/d]] - for portal names beginning with "D".
-- [[Module:Portal/images/e]] - for portal names beginning with "E".
-- [[Module:Portal/images/f]] - for portal names beginning with "F".
-- [[Module:Portal/images/g]] - for portal names beginning with "G".
-- [[Module:Portal/images/h]] - for portal names beginning with "H".
-- [[Module:Portal/images/i]] - for portal names beginning with "I".
-- [[Module:Portal/images/j]] - for portal names beginning with "J".
-- [[Module:Portal/images/k]] - for portal names beginning with "K".
-- [[Module:Portal/images/l]] - for portal names beginning with "L".
-- [[Module:Portal/images/m]] - for portal names beginning with "M".
-- [[Module:Portal/images/n]] - for portal names beginning with "N".
-- [[Module:Portal/images/p]] - for portal names beginning with "P".
-- [[Module:Portal/images/q]] - for portal names beginning with "Q".
-- [[Module:Portal/images/r]] - for portal names beginning with "R".
-- [[Module:Portal/images/s]] - for portal names beginning with "S".
-- [[Module:Portal/images/t]] - for portal names beginning with "T".
-- [[Module:Portal/images/u]] - for portal names beginning with "U".
-- [[Module:Portal/images/v]] - for portal names beginning with "V".
-- [[Module:Portal/images/w]] - for portal names beginning with "W".
-- [[Module:Portal/images/x]] - for portal names beginning with "X".
-- [[Module:Portal/images/y]] - for portal names beginning with "Y".
-- [[Module:Portal/images/z]] - for portal names beginning with "Z".
-- [[Module:Portal/images/other]] - for portal names beginning with any other letters. This includes numbers,
-- letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]] - for adding aliases for existing portal names. Use this page for variations
-- in spelling and diacritics, etc., no matter what letter the portal begins with.
-- When adding entries, please use alphabetical order. The format of the images table entries is as follows:
-- ["portal name"] = "image.svg",
-- The portal name should be the name of your portal, in lower case. For example, the portal name for
-- "Portal:United Kingdom" would be "united kingdom". The image name should be capitalised normally, and the "File:"
-- namespace prefix should be omitted.
]==]
return {
["oaxaca"] = "Flag of Oaxaca.svg|border|link=|alt=flag",
["occult"] = "Pentacle 2.svg|link=|alt=",
["oceania"] = "大洋.png|alt=icon",
["ocean"] = "Waves in pacifica 1.jpg|alt=icon",
["oceans"] = "Waves in pacifica 1.jpg|alt=icon",
["odense"] = "Coat of arms of Odense.svg|alt=icon",
["odessa"] = "Flag of Odessa.svg|alt=flag",
["odisha"] = "Seal of Odisha.png|link=|alt=seal",
["ohio"] = "Flag of Ohio.svg|link=|alt=flag",
["ohio wesleyan university"] = "ElliottHallOWU.jpg|link=|alt=photo",
["oklahoma"] = "Flag of Oklahoma.svg|border|link=|alt=flag",
["olives"] = "NCI 2 green olives.jpg|link=|alt=",
["olympic games"] = "Olympic Rings.svg|link=|alt=",
["olympics"] = "Olympic Rings.svg|link=|alt=",
["omaha"] = "Flag of Omaha, Nebraska.jpg|link=|alt=flag",
["oman"] = "Flag of Oman.svg|border|link=|alt=flag",
["ontario"] = "Flag of Ontario.svg|border|link=|alt=flag",
["ontario regions"] = "Ontario-flag-contour.png|link=|alt=",
["opera"] = "Operalogo.svg|alt=icon",
["oregon"] = "Flag of Oregon.svg|border|link=|alt=flag",
["organic chemistry"] = "Covalent.svg|alt=icon",
["organized labour"] = "Syndicalism.svg|alt=icon",
["oriental orthodoxy"] = "CopticCross.jpg|link=|alt=",
["origami"] = "Origami-crane.jpg|alt=icon",
["osaka"] = "Flag of Osaka City.svg|border|link=|alt=flag",
["osaka university"] = "Toyonaka stone.png|alt=icon",
["oscar wilde"] = "Oscar Wilde, 1882.jpg|link=|alt=",
["ossetian"] = "Idioma osetio.png|border|link=Ossetian language|alt=map",
["ottawa"] = "Flag of Ottawa, Ontario.svg|border|link=|alt=flag",
["ottoman empire"] = "Flag of the Ottoman Empire.svg|border|link=|alt=flag",
["outlines"] = "Global thinking.svg|link=|alt=",
["oxfordshire"] = "EnglandOxfordshire.png|alt=icon",
["oz"] = "Oz flag.svg|alt=icon"
}
fb254fb478a7be48fd87d03b9e5017a96ddb900c
Template:Order of magnitude
10
137
290
289
2022-09-04T15:25:10Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{safesubst:<noinclude/>#ifexpr:{{{1|0}}}=0
|{{safesubst:<noinclude/>#ifexpr:abs{{{1|0}}}1=1
|0
|{{safesubst:<noinclude/>#expr:floor((ln(abs{{{1}}}1)/ln10)+1)}}
}}
|{{safesubst:<noinclude/>#expr:floor((ln(abs({{{1|0}}}) )/ln 10)+1E((abs{{{1|0}}}>1E100 or abs{{{1|0}}}<1E-100)-14))}}
}}</includeonly><noinclude>
{{documentation}}
</noinclude>
cede5694e8ebb404ecdd17ae1f8e1c5d19562728
Template:DEC
10
138
292
291
2022-09-04T15:25:10Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{Str rep|{{{1}}}|-|−}}°{{#ifeq: {{{2|+}}}|{{{2|-}}}| {{{2|}}}′|}}{{#ifeq: {{{3|+}}}|{{{3|-}}}| {{{3|}}}″|}}<noinclude>
{{documentation}}
</noinclude>
6927f28c38d0a50c1b2b56e84804d862ad50264a
Template:RA
10
139
294
293
2022-09-04T15:25:11Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{nowrap|{{#if:{{{1|}}}|{{{1}}}<sup>h</sup>|}} {{#if:{{{2|}}}|{{{2}}}<sup>m</sup>|}} {{#if:{{{3|}}}|{{{3|}}}<sup>s</sup>|}}}}<noinclude>
{{documentation}}
</noinclude>
f457f7f0663d084c3d3296af8b827dc417ce0ac4
Template:Sky
10
140
296
295
2022-09-04T15:25:11Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude></noinclude><includeonly>{{#ifeq:{{{display|}}}|inline|<span class="sky-coordinates-inline plainlinks nourlexpansion">[[File:Jupiter and moon.png|20px|link=|Sky map]] [http://www.wikisky.org/?ra={{#expr:{{trim|{{{1}}}}}+{{trim|{{{2}}}}}/60+{{trim|{{{3}}}}}/3600}}&de={{#expr:{{trim|{{{4|+}}}}}{{trim|{{{5}}}}}+{{trim|{{{4|+}}}}}{{trim|{{{6}}}}}/60+{{trim|{{{4|+}}}}}{{trim|{{{7}}}}}/3600}}&zoom={{#expr:ln{{{8|100000}}}/ln10+1 round 0}}&show_grid=1&show_constellation_lines=1&show_constellation_boundaries=1&show_const_names=1&show_galaxies=1&img_source=IMG_all {{trim|{{{1}}}}}<sup>h</sup> {{trim|{{{2}}}}}<sup>m</sup> {{trim|{{{3}}}}}<sup>s</sup>, {{#ifeq:{{trim|{{{4}}}}}|-|−|{{trim|{{{4}}}}} }}{{trim|{{{5}}}}}° {{trim|{{{6}}}}}′ {{trim|{{{7}}}}}″]</span>|<indicator name="01-sky-coordinates"><templatestyles src="Template:Sky/styles.css" /><!--
This mostly repeats the previous statement, but i'm to lazy to write a lua module for it, try to keep it in sync --><span class="sky-coordinates-display plainlinks nourlexpansion">[[Celestial coordinate system|Coordinates]]: [[File:Jupiter and moon.png|20px|link=|Sky map]] [http://www.wikisky.org/?ra={{#expr:{{trim|{{{1}}}}}+{{trim|{{{2}}}}}/60+{{trim|{{{3}}}}}/3600}}&de={{#expr:{{trim|{{{4|+}}}}}{{trim|{{{5}}}}}+{{trim|{{{4|+}}}}}{{trim|{{{6}}}}}/60+{{trim|{{{4|+}}}}}{{trim|{{{7}}}}}/3600}}&zoom={{#expr:ln{{{8|100000}}}/ln10+1 round 0}}&show_grid=1&show_constellation_lines=1&show_constellation_boundaries=1&show_const_names=1&show_galaxies=1&img_source=IMG_all {{trim|{{{1}}}}}<sup>h</sup> {{trim|{{{2}}}}}<sup>m</sup> {{trim|{{{3}}}}}<sup>s</sup>, {{#ifeq:{{trim|{{{4}}}}}|-|−|{{trim|{{{4}}}}} }}{{trim|{{{5}}}}}° {{trim|{{{6}}}}}′ {{trim|{{{7}}}}}″]</span></indicator>
}}</includeonly><noinclude>{{documentation}}</noinclude>
0820a25c62d725441979785de033585a0ffa870e
Template:Solar luminosity
10
141
298
297
2022-09-04T15:25:11Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar luminosity|<var>L</var><sub>☉</sub>]]
|<var>L</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
fb6372ee064d487f11d117a91d6ae84d9980f19f
Template:Engvar
10
142
300
299
2022-09-04T15:25:11Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#invoke:Engvar|variants}}<noinclude>
{{documentation}}
</noinclude>
8a5e5d43fff0053bf6bd7fab7f761a6be4c05d21
Module:Engvar
828
143
302
301
2022-09-04T15:25:12Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
-- This module implements Template:Engvar.
-- Template:Engvar is to be build into the template (like an infobox), with default & variant spellings defined.
-- That template should also allow parameter '|engvar=' for the editor (article page).
-- The module/template Engvar then returns the spelling variant as is set in that article (for example '|engvar=en-GB').
-- The defaultWord is returned, unless the engvar input hits on a defined (en-XX) variant word.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local gsub = string.gsub
local lower = string.lower
local upper = string.upper
function p.variants(frame)
local args = getArgs(frame)
return p._variants(args)
end
function p._variants(args)
local returnWord = nil
local defaultWord = args.defaultWord or ''
if args.engvar == nil then
-- Nothing to look for; use defaultWord right away
returnWord = defaultWord
elseif args.defaultLang == gsub(lower(args.engvar), '^en%-(%w%w)$', formatISO) then
-- By the defaultLang, the defaultWord is asked
returnWord = defaultWord
else
returnWord = args[gsub(lower(args.engvar), '^en%-(%w%w)$', formatISO)]
end
if returnWord == nil then
-- No hit so far. Search by words in the engvar entered, checking the list
local useLang = engvarLang(args.engvar)
if useLang == nil then
returnWord = defaultWord .. addMaintCat(args)
else
returnWord = args[useLang] or defaultWord
end
end
return returnWord
end
-- Returns arguments and intermediate result. Plus the template result, in front.
function p.explain(frame)
local args = getArgs(frame)
local ret = {}
table.insert(ret, '\n\n: Settings:')
table.insert(ret, 'defaultWord=' .. (args.defaultWord or '') .. '; ')
table.insert(ret, 'defaultLang=' .. (args.defaultLang or '') .. '; ')
table.insert(ret, 'engvarCat=' .. (args.engvarCat or '[default:yes]') .. '; ')
table.insert(ret, 'engvarCatSort=' .. (args.engvarCatSort or ''))
table.insert(ret, '\n\n: engvar=' .. (args.engvar or '') .. ' [input] ')
local useLang = engvarLang(args.engvar or '')
table.insert(ret, ' => Engvar code [used]: >' .. (useLang or '') .. '<.')
for k, v in pairs(args) do
if k == 'en-UK' then
table.insert(ret, k .. ' ? better: use "en-GB"; ')
elseif k == 'en-SA' then
table.insert(ret, k .. ' ? misleading; use "en-ZA"; ')
end
if k == 'defaultWord' then
elseif k == 'defaultLang' then
elseif k == 'engvar' then
elseif k == 'engvarcat' then
elseif k == gsub(lower(k), '^en%-(%w%w)$', formatISO) then
table.insert(ret, k .. '=' .. v .. '; ')
else
table.insert(ret, k .. ' [not standard:]=' .. v .. '; ')
end
end
return (args.engvar or '') .. ' => ' .. p._variants(args) .. table.concat(ret, ' ')
end
-- Turn a match into pattern 'en-XX'
function formatISO(country)
return ('en-' .. upper(country) or '')
end
function engvarLang(searchEngvar)
-- Search verbose language identifiers to ISO-format 'en-XX'
-- Assumed: not a blank string '' to search
local match = string.match
searchEngvar = gsub(searchEngvar, '^%s*en%-(.*)', '%1') -- rm any opening 'en-'.
searchEngvar = gsub(lower(searchEngvar), '[%s%(%)%-]', '') -- To lc, remove all: (, ) , ws, hyphen.
local useLang
--Special codes
if match(searchEngvar, 'oxford')
or searchEngvar == 'oed' then
useLang = 'en-OED' -- 'oxford' to catch before anyting 'british'
elseif match(searchEngvar, 'iupac') then
useLang = 'en-IUPAC' -- chemistry
-- Very often used
elseif match(searchEngvar, 'british')
or searchEngvar == 'uk'
or searchEngvar == 'gbr' then
useLang = 'en-GB'
elseif searchEngvar == 'us'
or match(searchEngvar, 'unitedstates')
or searchEngvar == 'american'
or searchEngvar == 'usa' then
useLang = 'en-US'
elseif match(searchEngvar, 'australia')
or searchEngvar == 'aus' then
useLang = 'en-AU'
-- Often used
elseif match(searchEngvar, 'india')
or searchEngvar == 'ind' then
useLang = 'en-IN'
elseif searchEngvar == 'newzealand'
or searchEngvar == 'nzl' then
useLang = 'en-NZ'
elseif match(searchEngvar, 'southafrica') -- not: en-SA
or searchEngvar == 'zaf' then
useLang = 'en-ZA'
elseif searchEngvar == 'canada'
or searchEngvar == 'can' then
useLang = 'en-CA'
elseif match(searchEngvar, 'hiberno')
or match(searchEngvar, 'ireland')
or match(searchEngvar, 'irish')
or searchEngvar == 'irl' then
useLang = 'en-EI'
elseif match(searchEngvar, 'hongkong')
or searchEngvar == 'hkg' then
useLang = 'en-HK'
-- Less often used
elseif match(searchEngvar, 'jamaica')
or searchEngvar == 'jam' then
useLang = 'en-JM'
elseif match(searchEngvar, 'malawi')
or searchEngvar == 'mwi' then
useLang = 'en-MW'
elseif match(searchEngvar, 'nigeria')
or searchEngvar == 'nga' then
useLang = 'en-NG'
elseif match(searchEngvar, 'pakistan')
or searchEngvar == 'pak' then
useLang = 'en-PK'
elseif match(searchEngvar, 'philippine')
or searchEngvar == 'phl' then
useLang = 'en-PH'
elseif match(searchEngvar, 'scotland')
or match(searchEngvar, 'scottish')
or searchEngvar == 'sco' then
useLang = 'en-SCO' -- Has no alpha-2 code; not 'scotch'
elseif match(searchEngvar, 'singapore')
or searchEngvar == 'sgp' then
useLang = 'en-SG'
elseif match(searchEngvar, 'trinidad')
or match(searchEngvar, 'tobago')
or searchEngvar == 'tto' then
useLang = 'en-TT'
else
useLang = nil
end
return useLang
end
function addMaintCat(args)
local catMaintenance
if args.engvarCat == 'no' then
else
local title = mw.title.getCurrentTitle()
if title:inNamespaces(0) then -- 0=main, 10=templ, 828=module
if args.engvarCatSort then
catMaintenance = '|' .. args.engvarCatSort .. ', ' .. title.text
end
catMaintenance = '[[Category:Articles using an unknown Template:Engvar option' .. (catMaintenance or '') .. ']]'
end
end
return catMaintenance or ''
end
return p
c67c97cf2bc643d26781b77fd4b0d63383ab47a8
Template:End
10
144
304
303
2022-09-04T15:25:13Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>
{{#if:{{{html|}}}|</table>|{{!}}} }}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using end template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:End]] with unknown parameter "_VALUE_"|ignoreblank=y| html | 1<!--parameter does not do anything, but described in the documentation since 2015--> }}<noinclude>{{Documentation}}</noinclude>
6da317c960412bc7ac63866ddd9237d1a9bd914e
Template:Rnd
10
145
306
305
2022-09-04T15:25:13Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:Round]]
60d43fe6637b72ea57395979124e0c4cea5b4f9e
Template:Solar mass
10
146
308
307
2022-09-04T15:25:14Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar mass|<var>M</var><sub>☉</sub>]]
|<var>M</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
2a303d9d8a727c9f9ccc23508e1d17883808fbcc
Template:Solar radius
10
147
310
309
2022-09-04T15:25:14Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{#if:{{{1|}}}
|{{{1}}}
}}{{#if:{{{link|}}}
|[[Solar radius|<var>R</var><sub>☉</sub>]]
|<var>R</var><sub>☉</sub>
}}<noinclude>
{{documentation}}
</noinclude>
12c29f2ba83c64dcc96a015a59244428c531f452
Template:Lang-zh
10
148
312
311
2022-09-04T15:25:14Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#invoke:Lang-zh|Zh}}</includeonly><noinclude>{{documentation}}</noinclude>
09d0f2945fa94b8947d29d2329101bd511d11d2d
Template:Zh
10
149
314
313
2022-09-04T15:25:15Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:Lang-zh]]
{{R from move}}
6aa0af2f0918a28a55a7aa2f294fc53068c3b191
Module:Lang-zh
828
150
316
315
2022-09-04T15:25:15Z
SpaceMan
2
1 revision imported: Canopus
Scribunto
text/plain
require('Module:No globals')
local p = {}
-- articles in which traditional Chinese preceeds simplified Chinese
local t1st = {
["228 Incident"] = true,
["Chinese calendar"] = true,
["Lippo Centre, Hong Kong"] = true,
["Republic of China"] = true,
["Republic of China at the 1924 Summer Olympics"] = true,
["Taiwan"] = true,
["Taiwan (island)"] = true,
["Taiwan Province"] = true,
["Wei Boyang"] = true,
}
-- the labels for each part
local labels = {
["c"] = "Chinese",
["s"] = "simplified Chinese",
["t"] = "traditional Chinese",
["p"] = "pinyin",
["tp"] = "Tongyong Pinyin",
["w"] = "Wade–Giles",
["j"] = "Jyutping",
["cy"] = "Cantonese Yale",
["sl"] = "Sidney Lau",
["poj"] = "Pe̍h-ōe-jī",
["zhu"] = "Zhuyin Fuhao",
["l"] = "lit.",
["tr"] = "trans.",
}
-- article titles for wikilinks for each part
local wlinks = {
["c"] = "Chinese language",
["s"] = "simplified Chinese characters",
["t"] = "traditional Chinese characters",
["p"] = "pinyin",
["tp"] = "Tongyong Pinyin",
["w"] = "Wade–Giles",
["j"] = "Jyutping",
["cy"] = "Yale romanization of Cantonese",
["sl"] = "Sidney Lau romanisation",
["poj"] = "Pe̍h-ōe-jī",
["zhu"] = "Bopomofo",
["l"] = "Literal translation",
["tr"] = "Translation",
}
-- for those parts which are to be treated as languages their ISO code
local ISOlang = {
["c"] = "zh",
["t"] = "zh-Hant",
["s"] = "zh-Hans",
["p"] = "zh-Latn-pinyin",
["tp"] = "zh-Latn",
["w"] = "zh-Latn-wadegile",
["j"] = "yue-Latn-jyutping",
["cy"] = "yue-Latn",
["sl"] = "yue-Latn",
["poj"] = "nan-Latn",
["zhu"] = "zh-Bopo",
}
local italic = {
["p"] = true,
["tp"] = true,
["w"] = true,
["j"] = true,
["cy"] = true,
["sl"] = true,
["poj"] = true,
}
local superscript = {
["w"] = true,
["sl"] = true,
}
-- Categories for different kinds of Chinese text
local cats = {
["c"] = "[[Category:Articles containing Chinese-language text]]",
["s"] = "[[Category:Articles containing simplified Chinese-language text]]",
["t"] = "[[Category:Articles containing traditional Chinese-language text]]",
}
function p.Zh(frame)
-- load arguments module to simplify handling of args
local getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
return p._Zh(args)
end
function p._Zh(args)
local uselinks = not (args["links"] == "no") -- whether to add links
local uselabels = not (args["labels"] == "no") -- whether to have labels
local capfirst = args["scase"] ~= nil
local t1 = false -- whether traditional Chinese characters go first
local j1 = false -- whether Cantonese Romanisations go first
local testChar
if (args["first"]) then
for testChar in mw.ustring.gmatch(args["first"], "%a+") do
if (testChar == "t") then
t1 = true
end
if (testChar == "j") then
j1 = true
end
end
end
if (t1 == false) then
local title = mw.title.getCurrentTitle()
t1 = t1st[title.text] == true
end
-- based on setting/preference specify order
local orderlist = {"c", "s", "t", "p", "tp", "w", "j", "cy", "sl", "poj", "zhu", "l", "tr"}
if (t1) then
orderlist[2] = "t"
orderlist[3] = "s"
end
if (j1) then
orderlist[4] = "j"
orderlist[5] = "cy"
orderlist[6] = "sl"
orderlist[7] = "p"
orderlist[8] = "tp"
orderlist[9] = "w"
end
-- rename rules. Rules to change parameters and labels based on other parameters
if args["hp"] then
-- hp an alias for p ([hanyu] pinyin)
args["p"] = args["hp"]
end
if args["tp"] then
-- if also Tongyu pinyin use full name for Hanyu pinyin
labels["p"] = "Hanyu Pinyin"
end
if (args["s"] and args["s"] == args["t"]) then
-- Treat simplified + traditional as Chinese if they're the same
args["c"] = args["s"]
args["s"] = nil
args["t"] = nil
elseif (not (args["s"] and args["t"])) then
-- use short label if only one of simplified and traditional
labels["s"] = labels["c"]
labels["t"] = labels["c"]
end
local body = "" -- the output string
local params -- for creating HTML spans
local label -- the label, i.e. the bit preceeding the supplied text
local val -- the supplied text
-- go through all possible fields in loop, adding them to the output
for i, part in ipairs(orderlist) do
if (args[part]) then
-- build label
label = ""
if (uselabels) then
label = labels[part]
if (capfirst) then
label = mw.language.getContentLanguage():ucfirst(label)
capfirst = false
end
if (uselinks) then
label = "[[" .. wlinks[part] .. "|" .. label .. "]]"
end
if (labels[part] ~= "lit.") then
label = label .. ":"
else
label = "<small>" .. label .. "</small>"
end
label = label .. " "
end
-- build value
val = args[part]
if (cats[part]) and mw.title.getCurrentTitle().namespace == 0 then
-- if has associated category AND current page in article namespace, add category
val = cats[part] .. val
end
if (ISOlang[part]) then
-- add span for language if needed
params = {["lang"] = ISOlang[part]}
val = mw.text.tag({name="span",attrs=params, content=val})
elseif ((part == "l") or (part == "tr")) then
-- put literals in quotes
val = "'" .. val .. "'"
end
if (italic[part]) then
-- italicise
val = "<i>" .. val .. "</i>"
end
if string.match(val, "</?sup>") then val = val.."[[Category:Pages using template Zh with sup tags]]" end
if (superscript[part]) then
-- superscript
val = val:gsub("(%d)", "<sup>%1</sup>"):gsub("(%d)</sup>%*<sup>(%d)", "%1*%2"):gsub("<sup><sup>([%d%*]+)</sup></sup>", "<sup>%1</sup>")
end
-- add both to body
body = body .. label .. val .. "; "
end
end
if (body > "") then -- check for empty string
return string.sub(body, 1, -3) -- chop off final semicolon and space
else --no named parameters; see if there's a first parameter, ignoring its name
if (args[1]) then
-- if there is treat it as Chinese
label = ""
if (uselabels) then
label = labels["c"]
if (uselinks) then
label = "[[" .. wlinks["c"] .. "|" .. label .. "]]"
end
label = label .. ": "
end
-- default to show links and labels as no options given
if mw.title.getCurrentTitle().namespace == 0 then
-- if current page in article namespace
val = cats["c"] .. args[1]
else
val = args[1]
end
params = {["lang"] = ISOlang["c"]}
val = mw.text.tag({name="span",attrs=params, content=val})
return label .. val
end
return ""
end
end
return p
784d83ce2141b8e5828575b09c81e5f62a637998
Template:ErrorBar2
10
151
318
317
2022-09-04T15:25:15Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<includeonly>{{#if:{{{2|}}}|{{#ifexpr: abs({{{2}}}) > abs({{{1}}} * {{{3}}})|approx. {{rnd|{{{1}}}|-{{order of magnitude|{{{2}}}}}}}|{{rnd|{{{1}}}|-{{order of magnitude|{{{2}}}}} }} ± {{rnd|{{{2}}}|-{{order of magnitude|{{{2}}}}} }} }} |{{{1}}} }}</includeonly><noinclude>
{{documentation}}
</noinclude>
7d3a83f90aace7dc6b51a308b64364e74e8bc666
Template:Starbox astrometry
10
152
320
319
2022-09-04T15:25:16Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||[[Astrometry]]}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}</th></tr><!--
--><tr><th colspan="2" style="text-align: center">{{{component1<includeonly>|</includeonly>}}}</tr><!--
-->{{#if:{{{radial_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Radial velocity]] (R<sub>v</sub>)'''</td><td>{{{radial_v}}} km/s</td></tr>}}<!--
-->{{#if:{{{total_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''Total velocity'''</td><td>{{{total_v}}} km/s</td></tr>}}<!--
-->{{#if:{{{prop_mo_ra<includeonly>|</includeonly>}}}{{{prop_mo_dec|}}}|<tr style="vertical-align:top;"><td>'''[[Proper motion]] (μ)'''</td><td> <abbr title="Right Ascension">RA:</abbr> {{{prop_mo_ra|}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote|}}} <br /> <abbr title="Declination">Dec.:</abbr> {{{prop_mo_dec|}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote|}}} </td></tr> }}<!--
-->{{#if:{{{parallax<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Stellar parallax|Parallax]] (π)'''</td><td>{{{parallax}}}{{#if:{{{p_error|}}}| ± {{{p_error}}} }} [[Milliarcsecond|mas]]{{#if:{{{parallax_footnote|}}}|{{{parallax_footnote}}} }}</td></tr>}}<!--
-->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}{{{dist_pc|}}}{{#if:{{{parallax|}}}|{{#if:{{{p_error|}}}|{{#ifexpr: {{{parallax|}}}-{{{p_error|}}}>0|yes}}}}}}|<tr style="vertical-align:top;"><td>'''[[Distance (astronomy)|Distance]]'''</td><!--
--><td><!--
-->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}{{{dist_pc|}}}||{{ErrorBar2|{{#expr: 3261.5638 / {{{parallax}}} }}|{{#if:{{{p_error|}}}|{{#expr: 3261.5638 * {{{p_error}}} / ({{{parallax}}} * {{{parallax}}}) }} }}|0.1}} [[Light-year|ly]] <br />({{ErrorBar2|{{#expr: 1000.0 / {{{parallax}}} }}|{{#if:{{{p_error|}}}|{{#expr: 1000.0 * {{{p_error}}} / ({{{parallax}}} * {{{parallax}}}) }} }}|0.1}} [[Parsec|pc]])}}<!-- -->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}|{{{dist_ly}}} [[Light-year|ly]] {{#if:{{{dist_pc|}}}|<br />({{{dist_pc}}} [[Parsec|pc]])}}|{{#if:{{{dist_pc|}}}|{{{dist_pc}}} [[Parsec|pc]]}}}}{{{dist_footnote|}}}<!--
--></td></tr>}}<!--
-->{{#if:{{{absmag_v<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute magnitude]] (M<sub>V</sub>)'''</td><td>{{{absmag_v}}}</td></tr>}}<!--
-->{{#if:{{{absmag_bol<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute bolometric<br>magnitude]] (M<sub>bol</sub>)'''</td><td>{{{absmag_bol}}}</td></tr>}}<!--
--><tr><th colspan="2" style="text-align: center">{{{component2<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{radial_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Radial velocity]] (R<sub>v</sub>)'''</td><td>{{{radial_v2}}} km/s</td></tr>}}<!--
-->{{#if:{{{total_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''Total velocity'''</td><td>{{{total_v2}}} km/s</td></tr>}}<!--
-->{{#if:{{{prop_mo_ra2<includeonly>|</includeonly>}}}{{{prop_mo_dec2|}}}|<tr style="vertical-align:top;"><td>'''[[Proper motion]] (μ)'''</td><td> <abbr title="Right Ascension">RA:</abbr> {{{prop_mo_ra2|-}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote2|}}} <br /> <abbr title="Declination">Dec.:</abbr> {{{prop_mo_dec2|-}}} [[Milliarcsecond|mas]]/[[Year|yr]]{{{pm_footnote2|}}} </td></tr> }}<!--
-->{{#if:{{{parallax2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Stellar parallax|Parallax]] (π)'''</td><td>{{{parallax2}}}{{#if:{{{p_error2|}}}| ± {{{p_error2}}}}} [[Milliarcsecond|mas]]{{#if:{{{parallax_footnote2|}}}|{{{parallax_footnote2}}}}}</td></tr>}}<!--
-->{{#if:{{{dist_ly2<includeonly>|</includeonly>}}}{{{dist_pc2|}}}{{{parallax2|}}}|<tr style="vertical-align:top;"><td>'''[[Distance (astronomy)|Distance]]'''</td><!--
--><td><!--
-->{{#if:{{{dist_ly2<includeonly>|</includeonly>}}}{{{dist_pc2|}}}||{{ErrorBar2|{{#expr: 3261.5638 / {{{parallax2}}} }}|{{#if:{{{p_error2|}}}|{{#expr: 3261.5638 * {{{p_error2}}} / ({{{parallax2}}} * {{{parallax2}}}) }} }}|0.1}} [[Light-year|ly]] <br />({{ErrorBar2|{{#expr: 1000.0 / {{{parallax2}}} }}|{{#if:{{{p_error2|}}}|{{#expr: 1000.0 * {{{p_error2}}} / ({{{parallax2}}} * {{{parallax2}}}) }} }}|0.1}} [[Parsec|pc]])}}<!-- -->{{#if:{{{dist_ly<includeonly>|</includeonly>}}}|{{{dist_ly2}}} [[Light-year|ly]] {{#if:{{{dist_pc2|}}}|<br />({{{dist_pc2}}} [[Parsec|pc]])}}|{{#if:{{{dist_pc2|}}}|{{{dist_pc2}}} [[Parsec|pc]]}}}}<!--
--></td></tr>}}<!-- -->{{#if:{{{absmag_v2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute magnitude]] (M<sub>V</sub>)'''</td><td>{{{absmag_v2}}}</td></tr>}}<!-- -->{{#if:{{{absmag_bol2<includeonly>|</includeonly>}}}|<tr style="vertical-align:top;"><td>'''[[Absolute magnitude|Absolute bolometric<br>magnitude]] (M<sub>bol</sub>)'''</td><td>{{{absmag_bol2}}}</td></tr>}}<noinclude>
|}
{{Documentation}}
</noinclude>
e92454f250713fd8ce29da215c7da5e8ac87b802
Template:Starbox begin
10
153
322
321
2022-09-04T15:25:16Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{| class="infobox" style="width: 22em; font-size: 88%; <!-- text-align: left; --> line-height: 1.5em"
|+ style="font-size: 125%; font-weight: bold" | {{{name<includeonly>|{{PAGENAME}}</includeonly>}}}<noinclude>
|}{{Documentation}}</noinclude>
115f5bb26dd6bc3e6032bfe5080e62fffdb69a80
Template:Starbox catalog
10
154
324
323
2022-09-04T15:25:17Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">[[Star catalogue|Other designations]]</th></tr><!--
--><tr><td colspan="2"><div style="width: 250px;"> {{{names<includeonly>|</includeonly>}}} </div></td></tr><!--
-->{{#if:{{{component1<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component1}}}''': {{{names1}}}</td></tr>}}<!--
-->{{#if:{{{component2<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component2}}}''': {{{names2}}}</td></tr>}}<!--
-->{{#if:{{{component3<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component3}}}''': {{{names3}}}</td></tr>}}<!--
-->{{#if:{{{component4<includeonly>|</includeonly>}}}|<tr><td colspan="2">'''{{{component4}}}''': {{{names4}}}</td></tr>}}<noinclude>
|}
{{Documentation}}
</noinclude>
5a833fd635cee397f343a44ca1cb8ea26ae44be3
Template:Starbox character
10
155
326
325
2022-09-04T15:25:17Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude>
|-
! style="background-color: #FFFFC0; text-align: center;" colspan="2"| {{#if:{{{no_heading|}}}||Characteristics}}
|-
{{#if:{{{component|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component}}}
}}
|-
{{#if:{{{component1|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component1}}}
}}
|- style="vertical-align:top"
{{#if:{{{type|}}}|
! style="text-align:left" {{!}} [[Stellar evolution|Evolutionary stage]]
{{!}} {{{type}}}
}}
|- style="vertical-align:top"
{{#if:{{{class|}}}|
! style="text-align:left" {{!}} [[Stellar classification|Spectral type]]
{{!}} {{{class}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_1_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude]] ({{{appmag_1_passband|}}})
{{!}} {{{appmag_1}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_2_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_2_passband|}}})
{{!}} {{{appmag_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_3_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_3_passband|}}})
{{!}} {{{appmag_3}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_4_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_4_passband|}}})
{{!}} {{{appmag_4}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_5_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_5_passband|}}})
{{!}} {{{appmag_5}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_6_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_6_passband|}}})
{{!}} {{{appmag_6}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_7_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_7_passband|}}})
{{!}} {{{appmag_7}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_8_passband|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_8_passband|}}})
{{!}} {{{appmag_8}}}
}}
|- style="vertical-align:top"
{{#if:{{{u-b|}}}|
! style="text-align:left" {{!}} U−B {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{u-b}}}
}}
|- style="vertical-align:top"
{{#if:{{{b-v|}}}|
! style="text-align:left" {{!}} B−V {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{b-v}}}
}}
|- style="vertical-align:top"
{{#if:{{{v-r|}}}|
! style="text-align:left" {{!}} V−R {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{v-r}}}
}}
|- style="vertical-align:top"
{{#if:{{{r-i|}}}|
! style="text-align:left" {{!}} R−I {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{r-i}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-h|}}}|
! style="text-align:left" {{!}} J−H {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-h}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-k|}}}|
! style="text-align:left" {{!}} J−K {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-k}}}
}}
|- style="vertical-align:top"
{{#if:{{{variable|}}}|
! style="text-align:left" {{!}} [[Variable star|Variable type]]
{{!}} {{{variable}}}
}}
|- style="vertical-align:top"
{{#if:{{{component2|}}}|
! style="text-align:center" colspan="2" {{!}} {{{component2}}}
}}
|- style="vertical-align:top"
{{#if:{{{type2|}}}|
! style="text-align:left" {{!}} [[Stellar evolution|Evolutionary stage]]
{{!}} {{{type2}}}
}}
|- style="vertical-align:top"
{{#if:{{{class2|}}}|
! style="text-align:left" {{!}} [[Stellar classification|Spectral type]]
{{!}} {{{class2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_1_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude]] ({{{appmag_1_passband2|}}})
{{!}} {{{appmag_1_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_2_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_2_passband2|}}})
{{!}} {{{appmag_2_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_3_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_3_passband2|}}})
{{!}} {{{appmag_3_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_4_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_4_passband2|}}})
{{!}} {{{appmag_4_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_5_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_5_passband2|}}})
{{!}} {{{appmag_5_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_6_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_6_passband2|}}})
{{!}} {{{appmag_6_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_7_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_7_passband2|}}})
{{!}} {{{appmag_7_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{appmag_8_passband2|}}}|
! style="text-align:left" {{!}} [[Apparent magnitude|Apparent magnitude]] ({{{appmag_8_passband2|}}})
{{!}} {{{appmag_8_2}}}
}}
|- style="vertical-align:top"
{{#if:{{{u-b2|}}}|
! style="text-align:left" {{!}} U−B {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{u-b2}}}
}}
|- style="vertical-align:top"
{{#if:{{{b-v2|}}}|
! style="text-align:left" {{!}} B−V {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{b-v2}}}
}}
|- style="vertical-align:top"
{{#if:{{{v-r2|}}}|
! style="text-align:left" {{!}} V−R {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{v-r2}}}
}}
|- style="vertical-align:top"
{{#if:{{{r-i2|}}}|
! style="text-align:left" {{!}} R−I {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{r-i2}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-h2|}}}|
! style="text-align:left" {{!}} J−H {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-h2}}}
}}
|- style="vertical-align:top"
{{#if:{{{j-k2|}}}|
! style="text-align:left" {{!}} J−K {{engvar |defaultWord=[[color index]] |defaultLang=en-US |en-UK=[[colour index]] |engvar={{{engvar|}}} }}
{{!}} {{{j-k2}}}
}}
|- style="vertical-align:top"
{{#if:{{{variable2|}}}|
! style="text-align:left" {{!}} [[Variable star|Variable type]]
{{!}} {{{variable2}}}
}}<noinclude>
|}
{{Documentation}}
</noinclude>
bd7d2ca5352dd7b2dc3f58a1ac88cd9daf7194e3
Template:Starbox detail
10
156
328
327
2022-09-04T15:25:18Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||Details{{{source|}}}}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}</th></tr><!--
--><tr><th colspan="2" style="text-align: center">{{{component1<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{mass<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass}}} {{Solar mass|link=yes}}</td></tr>}}<!--
-->{{#if:{{{mass_mj<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass_mj}}} [[Jupiter mass|''M''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius}}} {{Solar radius|link=yes}}</td></tr>}}<!--
-->{{#if:{{{radius_rj<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_rj}}} [[Jupiter radius|''R''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius_km<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_km}}} [[kilometer|km]]</td></tr>}}<!--
-->{{#if:{{{luminosity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Luminosity]]'''</td><td>{{{luminosity}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_bolometric<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (bolometric)'''</td><td>{{{luminosity_bolometric}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_visual<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (visual, L<sub>V</sub>)'''</td><td>{{{luminosity_visual}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{habitable_inner<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] inner limit'''</td><td>{{{habitable_inner}}}</td></tr>}}<!--
-->{{#if:{{{habitable_outer<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] outer limit'''</td><td>{{{habitable_outer}}}</td></tr>}}<!--
-->{{#if:{{{gravity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Surface gravity]] (log ''g'')'''</td><td>{{{gravity}}} [[Centimetre–gram–second system of units|cgs]]</td></tr>}}<!--
-->{{#if:{{{temperature<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Effective temperature|Temperature]]'''</td><td>{{{temperature}}} [[Kelvin|K]]</td></tr>}}<!--
-->{{#if:{{{metal<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]'''</td><td>{{{metal}}}</td></tr>}}<!--
-->{{#if:{{{metal_fe<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]''' [Fe/H]</td><td>{{{metal_fe}}} [[Decimal exponent|dex]]</td></tr>}}<!--
-->{{#if:{{{rotation<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar rotation|Rotation]]'''</td><td>{{{rotation}}}</td></tr>}}<!--
-->{{#if:{{{rotational_velocity<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Projected rotational velocity|Rotational velocity]] (''v'' sin ''i'')'''</td><td>{{{rotational_velocity}}} km/s</td></tr>}}<!--
-->{{#if:{{{age<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar evolution|Age]]'''</td><td>{{{age}}} years</td></tr>}}<!--
-->{{#if:{{{age_myr<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age|}}}| |'''[[Stellar evolution|Age]]'''}}</td><td>{{{age_myr}}} [[megayear|Myr]]</td></tr>}}<!--
-->{{#if:{{{age_gyr<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age|}}}| |'''[[Stellar evolution|Age]]'''}}</td><td>{{{age_gyr}}} [[gigayear|Gyr]]</td></tr>}}<!--
--><tr><th colspan="2" style="text-align: center">{{{component2<includeonly>|</includeonly>}}}</th></tr><!--
-->{{#if:{{{mass2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass2}}} {{Solar mass|link=yes}}</td></tr>}}<!--
-->{{#if:{{{mass_mj2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar mass|Mass]]'''</td><td>{{{mass_mj2}}} [[Jupiter mass|''M''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius2}}} {{Solar radius|link=yes}}</td></tr>}}<!--
-->{{#if:{{{radius_rj2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_rj2}}} [[Jupiter radius|''R''<sub>Jup</sub>]]</td></tr>}}<!--
-->{{#if:{{{radius_km2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Radius]]'''</td><td>{{{radius_km2}}} [[kilometer|km]]</td></tr>}}<!--
-->{{#if:{{{luminosity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity'''</td><td>{{{luminosity2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_bolometric2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (bolometric)'''</td><td>{{{luminosity_bolometric2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{luminosity_visual2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''Luminosity (visual, L<sub>V</sub>)'''</td><td>{{{luminosity_visual2}}} {{Solar luminosity|link=yes}}</td></tr>}}<!--
-->{{#if:{{{habitable_inner2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] inner limit'''</td><td>{{{habitable_inner2}}}</td></tr>}}<!--
-->{{#if:{{{habitable_outer2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline:"><td>'''[[Habitable zone]] outer limit'''</td><td>{{{habitable_outer2}}}</td></tr>}}<!--
-->{{#if:{{{gravity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Surface gravity]] (log ''g'')'''</td><td>{{{gravity2}}} [[Centimetre–gram–second system of units|cgs]]</td></tr>}}<!--
-->{{#if:{{{temperature2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Effective temperature|Temperature]]'''</td><td>{{{temperature2}}} [[Kelvin|K]]</td></tr>}}<!--
-->{{#if:{{{metal2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]'''</td><td>{{{metal2}}}</td></tr>}}<!--
-->{{#if:{{if empty|{{{metal_fe2|}}}|{{{metal2_fe|}}}|<noinclude>x</noinclude>}}|<tr style="vertical-align:baseline;"><td>'''[[Metallicity]]''' [Fe/H]</td><td>{{{metal2_fe|{{{metal_fe2}}}}}} [[Decimal exponent|dex]]</td></tr>}}<!--
-->{{#if:{{{rotation2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Stellar rotation|Rotation]]'''</td><td>{{{rotation2}}}</td></tr>}}<!--
-->{{#if:{{{rotational_velocity2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Projected rotational velocity|Rotational velocity]] (''v'' sin ''i'')'''</td><td>{{{rotational_velocity2}}} km/s</td></tr>}}<!--
-->{{#if:{{{age2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>'''[[Star#Age_and_size_of_stars|Age]]'''</td><td>{{{age2}}} years</td></tr>}}<!--
-->{{#if:{{{age_myr2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age2|}}}| |'''[[Star#Age_and_size_of_stars|Age]]'''}}</td><td>{{{age_myr2}}} [[megayear|Myr]]</td></tr>}}<!--
-->{{#if:{{{age_gyr2<includeonly>|</includeonly>}}}|<tr style="vertical-align:baseline;"><td>{{#if:{{{age2|}}}| |'''[[Star#Age_and_size_of_stars|Age]]'''}}</td><td>{{{age_gyr2}}} [[gigayear|Gyr]]</td></tr>}}<noinclude>
|}
<!-- Please add categories to the /doc subpage; interwikis go to Wikidata, thank you! -->
{{Documentation}}
</noinclude>
7f2d91f20c11e77a3a015d033ec4771978d97588
Template:Starbox end
10
157
330
329
2022-09-04T15:25:18Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:End]]
{{Rcat shell|
{{Wikidata redirect}}
{{R from template shortcut}}
{{R with history}}
}}
ad342c0433bda993d648e9da241703291bbb98a6
Template:Starbox image
10
158
332
331
2022-09-04T15:25:19Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><td colspan="2" style="text-align:center;"><div style="text-align: center; margin-left:auto; margin-right:auto">{{{image}}}{{#ifeq:{{#invoke:String|sub|{{{image}}}|1|4}}|<div||<br/>}}{{{caption}}}{{#if:{{{credit|}}}|<br>'''Credit''': ''{{{credit}}}''}}</div></tr></td><noinclude>
|}
{{Documentation}}
</noinclude>
791822619c27809b308010e9b9fb71720d2f98f0
Template:Starbox observe
10
159
334
333
2022-09-04T15:25:19Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>{{Astro talk}}
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude>
|-
! style="text-align: center; background-color: #FFFFC0;" colspan="2" | Observation data<br/>{{#ifeq:{{{epoch}}}|[[J2000.0]] ([[International Celestial Reference System|ICRS]])|[[Epoch (astronomy)|Epoch]] [[J2000.0]] [[Equinox (celestial coordinates)|Equinox]] [[J2000.0]] ([[International Celestial Reference System|ICRS]])| [[Epoch (astronomy)|Epoch]] {{{epoch}}} [[Equinox (celestial coordinates)|Equinox]] {{{equinox|{{{epoch|}}}}}}}}
|- style="vertical-align:top"
! style="text-align:left" | [[Constellation]]
| {{{constell}}}
|- style="vertical-align:top"
{{#if:{{{pronounce<includeonly>|</includeonly>}}}|
! style="text-align:left" {{!}} [[WP:IPA for English|Pronunciation]]
{{!}} {{{pronounce}}}
}}
|- style="vertical-align:top"
! style="text-align:left" | {{nowrap|[[Right ascension]]}}
| {{{ra}}}
|- style="vertical-align:top"
! style="text-align:left" | [[Declination]]
| {{{dec}}}
|- style="vertical-align:top"
{{#if:{{{appmag_v<includeonly>|</includeonly>}}}|
! style="text-align:left" {{!}} {{nowrap|[[Apparent magnitude|Apparent magnitude]] (V)}}
{{!}} {{{appmag_v}}}
}}<noinclude>
|}
{{Documentation}}
</noinclude>
21bf36f2041ff2d017e71e8c048693e9ad9e15db
Template:Starbox reference
10
160
336
335
2022-09-04T15:25:19Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
<noinclude>
{| class="toccolours" style="float: right; clear: right; margin: 0 0 1em 1em; padding: 3px;"
</noinclude><tr><th style="background-color: #FFFFC0; text-align: center;" colspan="2">{{#if:{{{no_heading|}}}||Database references}}</th></tr>{{#if:{{{component|}}}|<tr style="text-align:center"><th colspan="2">{{{component}}}</th></tr>}}<!--
-->{{#if:{{{Simbad<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''[[SIMBAD]]'''</td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad}}} {{{sn|data}}}]</tr>}}<!--
-->{{#if:{{{Simbad2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad2}}} {{{sn2|data2}}}]</tr>}}<!--
-->{{#if:{{{Simbad3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad3}}} {{{sn3|data3}}}]</tr>}}<!--
-->{{#if:{{{Simbad4<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad4}}} {{{sn4|data4}}}]</tr>}}<!--
-->{{#if:{{{Simbad5<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad5}}} {{{sn5|data5}}}]</tr>}}<!--
-->{{#if:{{{Simbad6<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad6}}} {{{sn6|data6}}}]</tr>}}<!--
-->{{#if:{{{Simbad7<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad7}}} {{{sn7|data7}}}]</tr>}}<!--
-->{{#if:{{{Simbad8<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad8}}} {{{sn8|data8}}}]</tr>}}<!--
-->{{#if:{{{Simbad9<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://simbad.cds.unistra.fr/simbad/sim-id?Ident={{{Simbad9}}} {{{sn9|data9}}}]</tr>}}<!--
-->{{#if:{{{NSTED<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''[[Exoplanet Archive]]'''</td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED}}} {{{nn|data}}}]</tr>}}<!--
-->{{#if:{{{NSTED2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED2}}} {{{nn2|data2}}}]</tr>}}<!--
-->{{#if:{{{NSTED3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://exoplanetarchive.ipac.caltech.edu/cgi-bin/DisplayOverview/nph-DisplayOverview?objname={{{NSTED3}}} {{{nn3|data3}}}]</tr>}}<!--
-->{{#if:{{{ARICNS<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td>'''ARICNS'''</td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS}}}.htm {{{an|data}}}]</td></tr>}}<!--
-->{{#if:{{{ARICNS2<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS2}}}.htm {{{an2|data2}}}]</td></tr>}}<!--
-->{{#if:{{{ARICNS3<includeonly>|</includeonly>}}}|<tr style="vertical-align: top;"><td></td><td>[https://wwwadd.zah.uni-heidelberg.de/datenbanken/aricns/cnspages/4c{{{ARICNS3}}}.htm {{{an3|data3}}}]</td></tr>}}<!--
-->{{#if:{{{EPE<includeonly>|</includeonly>}}}|<tr><td>'''[[Extrasolar Planets Encyclopaedia|Extrasolar Planets<br />Encyclopaedia]]'''</td><td>[https://exoplanet.eu/star.php?st={{{EPE}}} data]</td></tr>}}<!--
-->{{#if:{{{KIC<includeonly>|</includeonly>}}}|<tr><td>'''[[Kepler Input Catalog|KIC]]'''</td><td>[https://archive.stsci.edu/kepler/data_search/search.php?action=Search&ktc_kepler_id={{{KIC}}} data]</td></tr>
}}<noinclude>
|}
{{Documentation}}
</noinclude>
f84999acae32fc7dacb316605220d28af5b2f06d
Template:Carina (constellation)
10
161
338
337
2022-09-04T15:25:20Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{Navbox
| name = Carina (constellation)
| title = [[Carina (constellation)|Carina constellation]]
| bodyclass = hlist
| state = {{{state|<noinclude>uncollapsed</noinclude>}}}
| group1 = [[Star]]s<br>([[List of stars in Carina|list]])
| list1 =
{{Navbox|subgroup
| group1 = [[Bayer designation|Bayer]]
| list1 =
* [[Canopus|α (Canopus)]]
* [[Beta Carinae|β (Miaplacidus)]]
* [[Epsilon Carinae|ε (Avior)]]
* [[Eta Carinae|η]]
* [[Theta Carinae|θ]]
* [[Iota Carinae|ι (Aspidiske)]]
* [[Upsilon Carinae|υ]]
* [[Chi Carinae|χ]]
* [[Omega Carinae|ω]]
| group3 = [[Variable star designation|Variable]]
| list3 =
* [[R Carinae|R]]
* [[HD 88366|S]]
* [[T Carinae|T (not variable)]]
* [[HD 95109|U]]
* [[V Carinae|V]]
* [[X Carinae|X]]
* [[Y Carinae|Y]]
* [[RT Carinae|RT]]
* [[UX Carinae|UX]]
* [[VY Carinae|VY]]
* [[WZ Carinae|WZ]]
* [[XY Carinae|XY]]
* [[XZ Carinae|XZ]]
* [[YZ Carinae|YZ]]
* [[AG Carinae|AG]]
* [[BO Carinae|BO]]
* [[CK Carinae|CK]]
* [[CR Carinae|CR]]
* [[DW Carinae|DW]]
* [[EM Carinae|EM]]
* [[EY Carinae|EY]]
* [[GG Carinae|GG]]
* [[GH Carinae|GH]]
* [[GL Carinae|GL]]
* [[GZ Carinae|GZ]]
* [[HH Carinae|HH]]
* [[HR Carinae|HR]]
* [[IW Carinae|IW]]
* [[IX Carinae|IX]]
* [[OY Carinae|OY]]
* [[PP Carinae|PP (p)]]
* [[QU Carinae|QU]]
* [[QX Carinae|QX]]
* [[HD 88661|QY]]
* [[QZ Carinae|QZ]]
* [[V337 Carinae|V337 (q)]]
* [[HD 65750|V341]]
* [[V343 Carinae|V343 (d)]]
* [[V344 Carinae|V344 (f)]]
* [[V345 Carinae|V345 (E)]]
* [[V348 Carinae|V348]]
* [[V357 Carinae|V357 (a)]]
* [[HD 92664|V364]]
* [[V368 Carinae|V368]]
* [[HD 91619|V369]]
* [[HD 92207|V370]]
* [[HD 96919|V371 (z<sup>2</sup>)]]
* [[V372 Carinae|V372]]
* [[HD 66194|V374]]
* [[V375 Carinae|V375]]
* [[V376 Carinae|V376 (b<sup>1</sup>)]]
* [[HD 92024|V381]]
* [[V382 Carinae|V382 (x)]]
* [[V386 Carinae|V386]]
* [[V390 Carinae|V390]]
* [[V392 Carinae|V392]]
* [[HD 90657|V398]]
* [[V399 Carinae|V399 (P)]]
* [[V403 Carinae|V403]]
* [[HD 60435|V409]]
* [[HD 96248|V414]]
* [[HR 2554|V415 (A)]]
* [[HD 94546|V428]]
* [[HD 96446|V430]]
* [[HD 97152|V431]]
* [[V448 Carinae|V448 (O)]]
* [[V450 Carinae|V450]]
* [[HR 3153|V460]]
* [[V461 Carinae|V461]]
* [[V469 Carinae|V469]]
* [[V473 Carinae|V473]]
* [[V478 Carinae|V478]]
* [[V482 Carinae|V482]]
* [[V486 Carinae|V486]]
* [[V487 Carinae|V487]]
* [[V492 Carinae|V492]]
* [[V495 Carinae|V495]]
* [[V507 Carinae|V507]]
* [[V514 Carinae|V514]]
* [[V518 Carinae|V518]]
* [[HD 92964|V519]]
* [[V520 Carinae|V520 (w)]]
* [[V522 Carinae|V522]]
* [[V524 Carinae|V524]]
* [[V528 Carinae|V528]]
* [[V532 Carinae|V532]]
* [[V533 Carinae|V533 (y)]]
* [[V535 Carinae|V535]]
* [[HD 307938|V557]]
* [[HD 93205|V560]]
* [[HD 85567|V596]]
* [[HD 87643|V640]]
* [[V655 Carinae|V655]]
* [[V906 Carinae|V906]]
| group4 = [[Bright Star Catalogue|HR]]
| list4 =
* [[HD 44267|2278]]
* [[HD 46569|2400]]
* [[HD 47001|2416]]
* [[N Carinae|2435 (N)]]
* [[HD 49517|2515]]
* [[HD 49689|2523]]
* [[HD 49705|2524]]
* [[HD 51210|2592]]
* [[HD 52603|2634]]
* [[HD 52622|2638]]
* [[HD 53047|2652]]
* [[HD 53349|2661]]
* [[HD 54732|2698]]
* [[HD 56239|2754]]
* [[HD 56705|2767]]
* [[HD 57852|2813]]
* [[HD 57917|2815]]
* [[HD 59219|2862]]
* [[HD 60060|2884]]
* [[HD 60228|2892]]
* [[HD 61031|2925]]
* [[HD 61248|2934 (Q)]]
* [[HD 61394|2941]]
* [[HD 62758|3006]]
* [[HD 62897|3012]]
* [[HD 63382|3031]]
* [[HD 63926|3056]]
* [[HD 64067|3062]]
* [[HD 64185|3070]]
* [[HD 65189|3100]]
* [[HD 65273|3105]]
* [[HD 65662|3120]]
* [[HD 65867|3133]]
* [[HD 65907|3138]]
* [[HD 65908|3139]]
* [[HD 66341|3152]]
* [[HD 66441|3156]]
* [[HR 3159|3159 (D)]]
* [[HD 66607|3161]]
* [[HD 67364|3180]]
* [[HD 68423|3217]]
* [[HD 68434|3218]]
* [[HR 3220|3220 (B)]]
* [[HD 69863|3260 (C)]]
* [[HD 70267|3274]]
* [[HD 70839|3293]]
* [[HD 70982|3298]]
* [[HD 72322|3368]]
* [[HD 73389|3414 (e<sup>2</sup>)]]
* [[HD 73390|3415 (e<sup>1</sup>)]]
* [[HD 73887|3432]]
* [[HD 74148|3443]]
* [[HD 74341|3455]]
* [[HD 74622|3471]]
* [[HD 75086|3489]]
* [[HD 76113|3536]]
* [[HD 76346|3549]]
* [[HD 76538|3560]]
* [[HD 76728|3571 (c)]]
* [[HD 77370|3598 (b<sup>2</sup>)]]
* [[HD 77615|3604]]
* [[HD 78293|3622]]
* [[HD 78632|3632]]
* [[HR 3643|3643 (G)]]
* [[HD 79447|3663 (i)]]
* [[HD 79698|3673]]
* [[HD 80094|3691]]
* [[HD 80126|3693]]
* [[HD 80230|3696 (g)]]
* [[HD 80671|3712]]
* [[HD 80951|3720]]
* [[HD 80950|3721]]
* [[HD 81101|3728 (k)]]
* [[HD 81502|3740]]
* [[HD 81613|3742]]
* [[HD 81830|3752]]
* [[HD 82068|3761]]
* [[HD 82347|3776]]
* [[HD 82350|3777]]
* [[HD 82406|3783]]
* [[HD 82858|3813]]
* [[HD 83095|3821 (H)]]
* [[HD 83183|3825 (h)]]
* [[HD 83944|3856 (m)]]
* [[HD 84121|3863]]
* [[HD 84152|3864]]
* [[HD 84810|3884 (l)]]
* [[HD 84850|3887]]
* [[HD 85655|3913]]
* [[HD 85656|3914]]
* [[HD 86606|3944]]
* [[HD 87238|3957]]
* [[HD 87283|3960]]
* [[HD 87436|3966]]
* [[HD 87438|3967]]
* [[HD 87543|3971]]
* [[HD 88323|3995]]
* [[HD 88473|4002]]
* [[HD 88825|4018]]
* [[HD 88907|4022]]
* [[HD 88981|4025 (M)]]
* [[HD 89263|4043]]
* [[HD 89715|4065]]
* [[HD 90264|4089 (L)]]
* [[HD 90289|4091]]
* [[HD 90454|4095]]
* [[HR 4102|4102 (I)]]
* [[HD 90630|4105]]
* [[HD 90853|4114 (s)]]
* [[HD 90874|4115]]
* [[HD 91056|4120]]
* [[HD 91270|4128]]
* [[HR 4138|4138 (K)]]
* [[HD 91496|4142]]
* [[HD 91533|4144]]
* [[HD 91767|4151]]
* [[HD 91942|4159 (r)]]
* [[HD 92063|4164 (t<sup>1</sup>)]]
* [[HD 92397|4177 (t<sup>2</sup>)]]
* [[HD 92436|4179]]
* [[HD 92682|4186]]
* [[HD 93163|4204]]
* [[HD 93194|4205]]
* [[HD 93344|4211]]
* [[HD 93359|4212]]
* [[HD 93372|V213]]
* [[HD 93502|4217]]
* [[HD 93540|4219]]
* [[HD 93549|4220]]
* [[HD 93607|4222]]
* [[HD 93662|4226]]
* [[HD 93943|4239]]
* [[HD 94510|4257 (u)]]
* [[HD 94650|4262]] <!--Search the HR number on SIMBAD for this star-->
* [[HD 94683|4266]]
* [[HD 95208|4279]]
* [[HD 95324|4290]]
* [[HD 96544|4323]]
* [[HD 96566|4325 (z<sup>1</sup>)]]
* [[HD 96568|4326]]
* [[HD 96706|4329]]
* [[HD 97472|4349]]
* [[HD 97583|4355]]
* [[HD 97670|4361]]
* [[HD 98560|4384]]
| group5 = [[Henry Draper Catalogue|HD]]
| list5 =
* [[HD 49219|49219]]
* [[HD 51608|51608]]
* [[HD 53143|53143]]
* [[HD 54967|54967]]
* [[HD 63765|63765]]
* [[HD 65216|65216]]
* [[HD 79699|79699]]
* [[HD 81896|81896]]
* [[HD 82458|82458]]
* [[HD 84046|84046]]
* [[HD 89805|89805]]
* [[HD 90074|90074]]
* [[HD 90657|90657]]
* [[HD 91094|91094]]
* [[HD 92399|92399]]
* [[HD 92536|92536]]
* [[HD 93129A|93129A]]
* [[HD 93250|93250]]
* [[HD 93403|93403]]
* [[HD 93645|93645]]
* [[HD 93695|93695]]
* [[HD 93738|93738]]
* [[HD 93739|93739]]
* [[HD 93843|93843]]
* [[HD 94275|94275]]
* [[HD 94305|94305]]
* [[HD 94491|94491]]
* [[HD 95086|95086]]
* [[HD 95122|95122]]
* [[HD 96088|96088]]
* [[HD 97950|97950]]
* [[HD 98025|98025]]
| group6 = [[Gliese catalogue|Gliese]]
| list6 =
| group7 = Other
| list7 =
* [[BPM 6502]]
* [[CPD−57° 2874]]
* [[CPD−59° 2628]]
* [[CPD−59° 2635]]
* [[DENIS J081730.0−615520|DEN 0817−6155]]
* [[AXP 1E 1048-59|1E 1048-59]]
* [[FO 15]]
* [[He 2-38]]
* [[Innes' star]]
* [[LHS 288]]
* [[NGC 3603-A1]]
* [[NGC 3603-B]]
* [[NGC 3603-C]]
* [[OGLE-TR-111]]
* [[OGLE-TR-113]]
* [[OGLE-TR-122]]
* [[OGLE-TR-123]]
* [[OGLE-TR-132]]
* [[OGLE-TR-182]]
* [[OGLE-TR-211]]
* [[OGLE2-TR-L9]]
* [[PSR J1048-5832]]
* [[PSR J1119-6127]]
* [[2S 0921-630]]
* [[Sher 25]]
* [[SS73 17]]
* [[Tr 16-104]]
* [[WR 16]]
* [[WR 18]]
* [[WR 20a]]
* [[WR 21a]]
* [[WR 22]]
* [[WR 23]]
* [[WR 24]]
* [[WR 25]]
* [[WR 30]]
* [[WR 30a]]
* [[WR 31a]]
* [[WR 40]]
* [[WR 42e]]
* [[AWI0005x3s]]
* [[WRA 751]] <!--Simbad ID is V432 Car-->
}}
|group2 = [[Star cluster|Star<br/>clusters]]
|list2 =
{{Navbox|subgroup
|group1=[[Stellar association|Association]]
|list1=
* [[Carina OB1]]
* [[Carina OB2]]
|group2=[[Open cluster|Open]]
|list2=
* [[Collinder 228]]
* [[IC 2602]]
* [[IC 2714]]
* [[NGC 2516]]
* [[NGC 2609]]
* [[NGC 3036]]
* [[NGC 3114]]
* [[NGC 3247]]
* [[NGC 3255]]
* [[NGC 3293]]
* [[NGC 3324]]
* [[NGC 3496]]
* [[NGC 3519]]
* [[NGC 3532]]
* [[NGC 3572]]
* [[NGC 3590]]
* [[NGC 3603]]
* [[Trumpler 14]]
* [[Trumpler 15]]
* [[Trumpler 16]]
* [[Westerlund 2]]
|group3=[[Globular cluster|Globular]]
|list3=
* [[NGC 2808]]
}}
|group3 = [[Nebula]]e
|list3=
{{Navbox|subgroup
|group1=[[H II region|H II]]
|list1=
* [[Carina Nebula]]
* [[NGC 3199]]
* [[NGC 3576]]
* [[NGC 3579]]
* [[NGC 3581]]
* [[NGC 3582]]
* [[NGC 3584]]
* [[NGC 3586]]
* [[RCW 49]]
|group2=[[Reflection nebula|Reflection]]
|list2=
* [[Homunculus Nebula]]
* [[IC 2220]]
* [[NGC 3503]]
|group3=[[Planetary nebula|Planetary]]
|list3=
* [[He 2-36]]
* [[Hen 2-47]]
* [[IC 2448]]
* [[IC 2501]]
* [[IC 2553]]
* [[NGC 2867]]
* [[NGC 3211]]
|group4=[[Supernova remnant|SNR]]
|list4=
* [[G290.1-0.8]]
|group5=[[Pulsar wind nebula|Pulsar wind]]
|list5=
* [[IGR J11014−6103]]
}}
|group4 = [[Galaxy|Galaxies]]
|list4=
{{Navbox|subgroup
|group1=[[Messier object|Messier]]
|list1=
|group2=[[New General Catalogue|NGC]]
|list2=
* [[NGC 2191|2191]]
* [[NGC 2369|2369]]
* [[NGC 2369A|2369A]]
* [[NGC 2369B|2369B]]
* [[NGC 2381|2381]]
* [[NGC 2417|2417]]
* [[NGC 2502|2502]]
* [[NGC 2640|2640]]
* [[NGC 2714|2714]]
* [[NGC 2788|2788]]
* [[NGC 2822|2822]]
* [[NGC 2836|2836]]
* [[NGC 2842|2842]]
* [[NGC 2887|2887]]
* [[NGC 3059|3059]]
* [[NGC 3136|3136]]
* [[NGC 3136A|3136A]]
* [[NGC 3136B|3136B]]
|group3=Other
|list3=
* [[Carina Dwarf Spheroidal Galaxy]]
}}
|group5=[[Galaxy cluster|Galaxy<br/>clusters]]
|list5=
* [[Abell 3391]]
* [[Abell 3395]]
* [[Bullet Cluster]]
|group6=Other
|list6=
* [[GRB 000131]]
* [[GRB 080916C]]
}}<noinclude>
== Documentation ==
{{Universe navboxes}}
[[Category:Stars of constellation templates|Carina]]
</noinclude>
b3e9a604f6e67f2ecee2dbda375f4d9ba3b2bc17
Template:Cite DR2
10
162
340
339
2022-09-04T15:25:20Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
#REDIRECT [[Template:Cite Gaia DR2]]
{{R from move}}
f105cdaa4ffd5d7683d35297a855d5e4fc5c1c16
Template:Cite Gaia DR2
10
163
342
341
2022-09-04T15:25:20Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{cite journal
| last1=Brown | first1=A. G. A.
| display-authors=etal
| collaboration=Gaia collaboration
| date=August 2018
| title=''Gaia'' Data Release 2: Summary of the contents and survey properties
| journal=[[Astronomy & Astrophysics]]
| volume=616 |at=A1
| arxiv=1804.09365
| bibcode=2018A&A...616A...1G
| bibcode-access=free
| doi=10.1051/0004-6361/201833051
| doi-access=free
| mode={{{mode|}}}
}}{{#if:{{{1|}}}| [http://vizier.u-strasbg.fr/viz-bin/VizieR-S?Gaia%20DR2%20{{Trim|{{{1|}}}}} Gaia DR2 record for this source] at [[VizieR]].}}<noinclude>
{{Documentation}}
</noinclude>
f0d86754ae543ff75617b1a118b720534de42335
Template:Odlist
10
164
344
343
2022-09-04T15:25:21Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{comma separated entries
<!-- Traditional/proper names, or exoplanet star designations -->
| {{{name<includeonly>|</includeonly>}}}
| {{{name2<includeonly>|</includeonly>}}}
| {{{name3<includeonly>|</includeonly>}}}
| {{{name4<includeonly>|</includeonly>}}}
| {{{name5<includeonly>|</includeonly>}}}
<!-- Bayer, Flamsteed, Gould, and variable star designations -->
| {{#if:{{{B|}}} |[[Bayer designation|{{{B}}}]]}}
| {{#if:{{{F|}}} |[[Flamsteed designation|{{{F}}}]]}}
| {{#if:{{{Gould|}}}|[[Gould designation|{{{Gould}}}]]}}
| {{#if:{{{V|}}} |[[Variable star designation|{{{V}}}]]}}
| {{#if:{{{NSV|}}} |[[New Catalogue of Suspected Variable Stars|NSV]] {{{NSV}}}}}
<!-- Commonly used designations like HD, HIP, HR -->
| {{#if:{{{AG|}}} |{{nowrap|[[Astronomische Gesellschaft Katalog|AG]]{{Str rep|{{{AG}}}|-|−}}}}}}
| {{#if:{{{BD<includeonly>|</includeonly>}}} |{{nowrap|[[Bonner Durchmusterung|BD]]{{Str rep|{{{BD}}}|-|−}}}}}}
| {{#if:{{{CD|}}} |{{nowrap|[[Cordoba Durchmusterung|CD]]{{Str rep|{{{CD}}}|-|−}}}}}}
| {{#if:{{{CP|}}} |{{nowrap|[[Cape Photographic Durchmusterung|CPD]]{{Str rep|{{{CP}}}|-|−}}}}}}
| {{#if:{{{CPD|}}} |{{nowrap|[[Cape Photographic Durchmusterung|CPD]]{{Str rep|{{{CPD}}}|-|−}}}}}}
| {{#if:{{{FK5|}}} |[[Fifth Fundamental Catalogue|FK5]] {{{FK5}}}}}
| {{#if:{{{Gaia DR1|}}} |{{nowrap|[[Star_catalogue#Gaia_Catalogue|Gaia DR1]] {{{Gaia DR1}}}}}}}
| {{#if:{{{Gaia DR2|}}} |{{nowrap|[[Star_catalogue#Gaia_Catalogue|Gaia DR2]] {{{Gaia DR2}}}}}}}
| {{#if:{{{GC|}}} |[[Boss General Catalogue|GC]] {{{GC}}}}}
| {{#if:{{{GJ<includeonly>|</includeonly>}}} |[[Gliese Catalogue of Nearby Stars|GJ]] {{{GJ}}}}}
| {{#if:{{{GJ2<includeonly>|</includeonly>}}} |GJ {{{GJ2}}}}}
| {{#if:{{{HD<includeonly>|</includeonly>}}} |[[Henry Draper Catalogue|HD]] {{{HD}}}}}
| {{#if:{{{HIP<includeonly>|</includeonly>}}} |[[Hipparcos Catalogue|HIP]] {{{HIP}}}}}
| {{#if:{{{HR<includeonly>|</includeonly>}}} |[[Harvard Revised catalogue|HR]] {{{HR}}}}}
| {{#if:{{{SAO<includeonly>|</includeonly>}}} |[[Smithsonian Astrophysical Observatory Star Catalog|SAO]] {{{SAO}}}}}
| {{#if:{{{PPM|}}} |[[Position and proper motion catalogue|PPM]] {{{PPM}}}}}
<!-- Double star catalogs -->
| {{#if:{{{ADS|}}} |[[Aitken Double Star Catalogue|ADS]] {{{ADS}}}}}
| {{#if:{{{CCDM|}}} |{{nowrap|[[Catalog of Components of Double and Multiple Stars|CCDM]] {{{CCDM}}}}}}}
| {{#if:{{{WDS<includeonly>|</includeonly>}}} |{{nowrap|[[Washington Double Star Catalog|WDS]] {{{WDS}}}}}}}
| {{#if:{{{DC|}}} |[[Discovery code|{{{DC}}}]]}}
<!-- Nearby/high-proper-motion star catalogues and the like-->
| {{#if:{{{AC|}}} |[[Carte du Ciel|AC]] {{{AC}}}}}
| {{#if:{{{BPM|}}} |[[Bruce Proper Motion survey|BPM]] {{{BPM}}}}}
| {{#if:{{{Ci 18|}}}|[[Cincinnati Observatory|Ci]] 18 {{{Ci 18}}}}}
| {{#if:{{{Ci 20|}}}|[[Cincinnati Observatory|Ci]] 20 {{{Ci 20}}}}}
| {{#if:{{{EGGR|}}} |[[Olin J. Eggen|EG]][[Jesse L. Greenstein|GR]] {{{EGGR}}}}}
| {{#if:{{{G|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G}}}}}}}
| {{#if:{{{G2|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G2}}}}}}}
| {{#if:{{{G3|}}} |{{nowrap|[[Henry L. Giclas catalogue|G]] {{{G3}}}}}}}
| {{#if:{{{L|}}} |[[Luyten|L]] {{{L}}}}}
| {{#if:{{{LAL|}}} |[[Histoire céleste française|LAL]] {{{LAL}}}}}
| {{#if:{{{LAWD|}}} |[[Luyten Atlas of White Dwarfs|LAWD]] {{{LAWD}}}}}
| {{#if:{{{LFT|}}} |[[Luyten Five-Tenths catalogue|LFT]] {{{LFT}}}}}
| {{#if:{{{LHS|}}} |[[Luyten Half-Second Catalogue|LHS]] {{{LHS}}}}}
| {{#if:{{{LP|}}} |[[Luyten-Palomar proper motion catalogue|LP]] {{{LP}}}}}
| {{#if:{{{LPM|}}} |[[Luyten Proper-Motion Catalogue|LPM]] {{{LPM}}}}}
| {{#if:{{{LSPM|}}} |{{nowrap|[[LSPM-North Catalog|LSPM]] {{{LSPM}}}}}}}
| {{#if:{{{LTT|}}} |[[Luyten Two-Tenths catalogue|LTT]] {{{LTT}}}}}
| {{#if:{{{NLTT|}}} |[[NLTT]] {{{NLTT}}}}}
| {{#if:{{{PLX|}}} |[[General Catalogue of Trigonometric Parallaxes|PLX]] {{{PLX}}}}}
| {{#if:{{{PM|}}} |[[Proper motion|PM]] {{{PM}}}}}
| {{#if:{{{PM2|}}} |[[Proper motion|PM]] {{{PM2}}}}}
| {{#if:{{{Ross|}}} |[[Ross catalogue|Ross]] {{{Ross}}}}}
| {{#if:{{{SCR|}}} |{{nowrap|[[Super-COSMOS RECONS|SCR]] {{{SCR}}}}}}}
| {{#if:{{{WD|}}} |{{nowrap|[[White dwarf|WD]] {{{WD}}}}}}}
| {{#if:{{{WD2|}}} |{{nowrap|[[White dwarf|WD]] {{{WD2}}}}}}}
| {{#if:{{{WD3|}}} |{{nowrap|[[White dwarf|WD]] {{{WD3}}}}}}}
| {{#if:{{{Wolf|}}} |[[Max Wolf|Wolf]] {{{Wolf}}}}}
<!-- Exoplanet surveys -->
| {{#if:{{{Kepler|}}} |{{nowrap|[[Kepler space telescope|Kepler]]-{{{Kepler}}}}}}}
| {{#if:{{{KOI|}}} |{{nowrap|[[Kepler object of interest|KOI]]-{{{KOI}}}}}}}
| {{#if:{{{KIC|}}} |{{nowrap|[[Kepler Input Catalog|KIC]] {{{KIC}}}}}}}
| {{#if:{{{EPIC|}}} |{{nowrap|[[Ecliptic Plane Input Catalog|EPIC]] {{{EPIC}}}}}}}
| {{#if:{{{TOI|}}} |{{nowrap|[[Tess object of interest|TOI]]-{{{TOI}}}}}}}
| {{#if:{{{TIC|}}} |{{nowrap|[[TESS Input Catalog|TIC]] {{{TIC}}}}}}}
<!-- Extensive star surveys -->
| {{#if:{{{TYC|}}} |{{nowrap|[[Tycho Catalogue|TYC]] {{{TYC}}}}}}}
| {{#if:{{{GCRV|}}} |{{nowrap|[[GCRV]] {{{GCRV}}}}}}}
| {{#if:{{{GSC|}}} |{{nowrap|[[Guide Star Catalog|GSC]] {{{GSC}}}}}}}
| {{#if:{{{IRAS|}}} |{{nowrap|[[IRAS]] {{{IRAS}}}}}}}
| {{#if:{{{2MASS|}}}|{{nowrap|[[2MASS]] {{{2MASS}}}}}}}
| {{#if:{{{2MASX|}}}|{{nowrap|[[2MASX]] {{{2MASX}}}}}}}
| {{#if:{{{DENIS|}}}|{{nowrap|[[DENIS]] {{{DENIS}}}}}}}
| {{#if:{{{WISE|}}} |{{nowrap|[[Wide-field Infrared Survey Explorer|WISE]] {{{WISE}}}}}}}
| {{#if:{{{WISEA|}}}|{{nowrap|[[Wide-field Infrared Survey Explorer|WISEA]] {{{WISEA}}}}}}}
<!-- Galaxy catalogs -->
| {{#if:{{{NGC|}}} |{{nowrap|[[New General Catalogue|NGC]] {{{NGC}}}}}}}
| {{#if:{{{IC|}}} |{{nowrap|[[Index Catalogue|IC]] {{{IC}}}}}}}
| {{#if:{{{Arp|}}} |{{nowrap|[[Atlas of Peculiar Galaxies|Arp]] {{{Arp}}}}}}}
| {{#if:{{{UGC|}}} |{{nowrap|[[Uppsala General Catalogue|UGC]] {{{UGC}}}}}}}
| {{#if:{{{UGCA|}}} |{{nowrap|[[UGCA]] {{{UGCA}}}}}}}
| {{#if:{{{LEDA|}}} |{{nowrap|[[Lyon-Meudon Extragalactic Database|LEDA]] {{{LEDA}}}}}}}
| {{#if:{{{MCG|}}} |{{nowrap|[[Morphological Catalogue of Galaxies|MCG]] {{{MCG}}}}}}}
| {{#if:{{{MRK|}}} |{{nowrap|[[Markarian galaxies|Mrk]] {{{MRK}}}}}}}
| {{#if:{{{PGC|}}} |{{nowrap|[[Principal Galaxies Catalogue|PGC]] {{{PGC}}}}}}}
| {{#if:{{{CGCG|}}} |{{nowrap|[[Catalogue of Galaxies and of Clusters of Galaxies|CGCG]] {{{CGCG}}}}}}}
| {{#if:{{{VV|}}} |{{nowrap|[[Vorontsov-Vel'yaminov Interacting Galaxies|VV]] {{{VV}}}}}}}
| {{#if:{{{KPG|}}} |KPG {{{KPG}}}}}
| {{#if:{{{SDSS|}}} |{{nowrap|[[Sloan Digital Sky Survey|SDSS]] {{{SDSS}}}}}}}
}}<noinclude>
{{documentation|content=
This template may be used to create a list of other designations within [[Template:Starbox catalog]] or [[Template:Infobox galaxy]].
== Usage ==
A blank template with all the possible parameters is given below. You may delete any unused parameters.
<pre>
{{odlist
| name =
| name2 =
| name3 =
| name4 =
| name5 =
| 2MASS = <!-- Two Micron All-Sky Survey -->
| AC = <!-- Carte du Ciel -->
| AG = <!-- Astronomische Gesellschaft Katalog -->
| ADS = <!-- Aitken Double Star Catalogue -->
| B = <!-- Bayer designation -->
| BD = <!-- Bonner Durchmusterung -->
| BPM = <!-- Bruce Proper Motion survey -->
| CCDM = <!-- Catalogue of Components of Double and Multiple Stars -->
| CD = <!-- Cordoba Durchmusterung -->
| Ci 18 = <!-- Cincinnati Observatory -->
| Ci 20 = <!-- Cincinnati Observatory -->
| CP = <!-- Cape Photographic Durchmusterung -->
| CPD = <!-- Cape Photographic Durchmusterung -->
| DC = <!-- Washington Double Star Catalog discovery code (see WDS) -->
| DENIS = <!-- Deep Near Infrared Survey of the Southern Sky -->
| EGGR = <!-- Olin J. Eggen -->
| EPIC = <!-- Ecliptic Plane Input Catalog -->
| F = <!-- Flamsteed designation -->
| FK5 = <!-- Fifth Fundamental Catalogue -->
| G = <!-- Henry L. Giclas catalogue -->
| G2 = <!-- Henry L. Giclas catalogue -->
| G3 = <!-- Henry L. Giclas catalogue -->
| Gaia DR1 = <!-- Gaia data release 1 -->
| Gaia DR2 = <!-- Gaia data release 2 -->
| GCRV = <!-- General Catalogue of Stellar Radial Velocities -->
| GJ = <!-- Gliese-Jahreiss catalogue -->
| GJ2 = <!-- Gliese-Jahreiss catalogue -->
| Gould = <!-- Uranometria Argentina catalogue -->
| GSC = <!-- Guide Star Catalog -->
| HD = <!-- Henry Draper Catalogue -->
| HIP = <!-- Hipparcos Catalogue -->
| HR = <!-- Harvard Revised catalogue -->
| IRAS = <!-- Infrared Astronomical Satellite -->
| Kepler = <!-- Kepler -->
| KIC = <!-- Kepler Input Catalogue -->
| KOI = <!-- Kepler Object of Interest -->
| L = <!-- Luyten -->
| LAL = <!-- Histoire céleste française -->
| LAWD = <!-- Luyten Atlas of White Dwarfs -->
| LDS = <!-- Luyten Double Stars catalogue -->
| LP = <!-- Luyten-Palomar proper motion catalogue -->
| LPM = <!-- Luyten Proper-Motion Catalogue -->
| LFT = <!-- Luyten Five-Tenths catalogue -->
| LHS = <!-- Luyten Half-Second Catalogue -->
| LSPM = <!-- LSPM-North Catalog -->
| LTT = <!-- Luyten Two-Tenths catalogue -->
| NLTT = <!-- New Luyten Two-Tenths Catalogue -->
| NSV = <!-- New Catalogue of Suspected Variable Stars -->
| PLX = <!-- General Catalogue of Trigonometric Parallaxes -->
| PM = <!-- Proper motion -->
| PM2 = <!-- Proper motion -->
| PPM = <!-- Position and proper motion catalogue -->
| Ross = <!-- Ross catalogue -->
| SAO = <!-- Smithsonian Astrophysical Observatory Star Catalogue -->
| SCR = <!-- Super-COSMOS RECONS -->
| TOI = <!-- Tess Object of Interest -->
| TYC = <!-- Tycho Catalogue -->
| V = <!-- Variable star designation -->
| WD = <!-- White dwarf -->
| WD2 = <!-- White dwarf -->
| WD3 = <!-- White dwarf -->
| WDS = <!-- Washington Double Star Catalog -->
| WISE = <!-- Wide-field Infrared Survey Explorer -->
| WISEA = <!-- Wide-field Infrared Survey Explorer - All-Sky -->
| Wolf = <!-- Max Wolf -->
}}</pre>
For galaxies, use this one:
<pre>
{{odlist
| name =
| name2 =
| name3 =
| name4 =
| name5 =
| Arp = <!-- Atlas of Peculiar Galaxies -->
| IC = <!-- Index Catalogue -->
| LEDA = <!-- Lyon-Meudon Extragalactic Database -->
| MCG = <!-- Morphological Catalogue of Galaxies -->
| MRK = <!-- Markarian galaxies -->
| NGC = <!-- New General Catalogue -->
| PGC = <!-- Principal Galaxies Catalogue -->
| UGC = <!-- Uppsala General Catalogue -->
| UGCA = <!-- Uppsala General Catalogue Addendum -->
| 2MASS = <!-- Two Micron All-Sky Survey -->
| 2MASX = <!-- Two Micron All-Sky Survey Extended Source Catalog -->
| CGCG = <!-- Catalogue of Galaxies and of Clusters of Galaxies -->
| VV = <!-- Vorontsov-Vel'yaminov Interacting Galaxies -->
| KPG = <!-- Karachentsev Catalogue of Isolated Pairs of Galaxies -->
| SDSS = <!-- Sloan Digital Sky Survey -->
}}</pre>
[[Category:Astronomy templates]]
}}</noinclude>
a5bf09051821f2310a8126a5829dc0cbd7e51dd9
Template:Cite simbad
10
165
346
345
2022-09-04T15:25:21Z
SpaceMan
2
1 revision imported: Canopus
wikitext
text/x-wiki
{{cite web
|title={{{title|<noinclude>Title</noinclude>}}}
|url=http://simbad.u-strasbg.fr/simbad/sim-basic?Ident{{=}}{{urlencode:{{{title|HD 20794}}}}}
|work=[[SIMBAD]]
|publisher=[[Centre de données astronomiques de Strasbourg]]
|access-date={{{access-date|{{{accessdate|}}}}}}
|mode={{{mode|}}}
|postscript={{{postscript|}}}
}}<noinclude>
{{documentation}}
</noinclude>
b219ca85a3c3d762999e98b05adb0b273a17f2b5
Template:Sky/styles.css
10
166
348
347
2022-09-04T15:25:21Z
SpaceMan
2
1 revision imported: Canopus
text
text/plain
/* {{pp-template}} */
/* Similiar to [[Template:Coord]] styling */
.sky-coordinates-display {
line-height: 1.5em;
text-align: right;
text-indent: 0;
text-transform: none;
white-space: nowrap;
}
body.skin-vector-legacy .sky-coordinates-display {
font-size: 85%;
}
fb0dd75a941049acd566292c9241b00d7088d099
Canopus
0
37
349
90
2022-09-04T15:28:19Z
SpaceMan
2
/* External links */
wikitext
text/x-wiki
{{short description|Bright giant star in the constellation of Carina}}
{{Other uses}}
{{Starbox begin
| name=Canopus
}}
{{Starbox image
| image=[[File:Canopus.jpg|255px]]
| caption=An image of Canopus by [[Expedition 6]]
}}
{{Starbox observe
| epoch=J2000
| constell=[[Carina (constellation)|Carina]]
| pronounce={{IPAc-en|k|ə|ˈ|n|oʊ|p|ə|s}}<ref>{{OED|Canopus}}</ref>
| ra={{RA|06|23|57.10988}}<ref name="van Leeuwen2007">{{cite journal | title=Validation of the new Hipparcos reduction | last1=van Leeuwen | first1=F. | journal=Astronomy and Astrophysics | volume=474 | issue=2 | pages=653–664 | date=2007 | arxiv=0708.1752 | bibcode=2007A&A...474..653V | doi=10.1051/0004-6361:20078357 | s2cid=18759600 }} [http://webviz.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b48255b3&-out.add=.&-source=I/311/hip2&recno=30362 Vizier catalog entry ]</ref>
| dec={{DEC|-52|41|44.3810}}<ref name="van Leeuwen2007"/>
| appmag_v=−0.74<ref name="Ducati 2002">{{cite journal | title=Catalogue of Stellar Photometry in Johnson's 11-color system | last1=Ducati | first1=J. R. | journal=CDS/ADC Collection of Electronic Catalogues | volume=2237 | pages=0 | date=2002 | bibcode=2002yCat.2237....0D }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b360304a&-out.add=.&-source=II/237/colors&recno=1155 Vizier catalog entry ]</ref>
}}
{{Starbox character
| type=
| class=A9 II<ref name=perkins>{{cite journal|bibcode=1989ApJS...69..301G|title=The early F-type stars – Refined classification, confrontation with Stromgren photometry, and the effects of rotation|journal=Astrophysical Journal Supplement Series|volume=69|pages=301|last1=Gray|first1=R. O.|last2=Garrison|first2=R. F.|year=1989|doi=10.1086/191315}}</ref><ref>{{cite journal|bibcode=1993ASPC...45...59L|title=A Spectroscopic Study of High Galactic Latitude F Supergiant Stars|journal=Luminous High-Latitude Stars. The International Workshop on Luminous High-Latitude Stars|volume=45|pages=59|last1=Lopez-Cruz|first1=O.|last2=Garrison|first2=R. F.|year=1993}}</ref>
| b-v=+0.15<ref name="Ducati 2002"/>
| u-b=+0.10<ref name="Ducati 2002"/>
| variable=
}}
{{Starbox astrometry
| radial_v={{val|20.3|0.5}}<ref name="Gontcharov 2007">{{cite journal | title=Pullkovo Compilation of Radial Velocities for 39495 Hipparcos stars in a common system | last1=Gontcharov | first1=G. A. | journal=Astronomy Letters | volume=32 | issue=1 | pages=759–771 | date=2007 | bibcode=2006AstL...32..759G | doi=10.1134/S1063773706110065|arxiv = 1606.08053 | s2cid=119231169 }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b5f60fbd&-out.add=.&-source=III/252/table8&recno=9232 Vizier catalog entry ]</ref>
| prop_mo_ra=19.93<ref name="van Leeuwen2007"/>
| prop_mo_dec=23.24<ref name="van Leeuwen2007"/>
| parallax=10.55
| p_error=0.56
| parallax_footnote=<ref name="van Leeuwen2007"/>
| absmag_v=–5.71<ref name=smiljanic2006/>
|arxiv = 1606.08053 }}
{{Starbox detail
| metal_fe=–0.07<ref name=smiljanic2006/>
| mass={{Val|8.0|0.3}}<ref name=vlti>{{cite journal|bibcode=2013MNRAS.434..437C|arxiv=1306.3288|title=Fundamental parameters of 16 late-type stars derived from their angular diameter measured with VLTI/AMBER|journal=Monthly Notices of the Royal Astronomical Society|volume=434|issue=1|pages=437–450|last1=Cruzalèbes|first1=P.|last2=Jorissen|first2=A.|last3=Rabbia|first3=Y.|last4=Sacuto|first4=S.|last5=Chiavassa|first5=A.|last6=Pasquato|first6=E.|last7=Plez|first7=B.|last8=Eriksson|first8=K.|last9=Spang|first9=A.|last10=Chesneau|first10=O.|year=2013|doi=10.1093/mnras/stt1037|s2cid=49573767}}</ref> (2013)<br/>{{val|10.1|0.1}}<ref name=Tetzlaff2011/> (2011)
| radius={{Val|71|4}}<ref name=vlti/> (2013)<br>{{val|73.3|5.2}}<ref name=DomicianoDeSouza>{{cite journal|doi=10.1051/0004-6361/202140478|title=Refined fundamental parameters of Canopus from combined near-IR interferometry and spectral energy distribution|year=2021|last1=Domiciano De Souza|first1=A.|last2=Zorec|first2=J.|last3=Millour|first3=F.|last4=Le Bouquin|first4=J.-B.|last5=Spang|first5=A.|last6=Vakili|first6=F.|journal=Astronomy & Astrophysics|volume=654|pages=A19|arxiv=2109.07153|bibcode=2021A&A...654A..19D|s2cid=237513623}}</ref> (2021)
| gravity={{Val|1.70|0.05}}<ref name=DomicianoDeSouza/>
| rotational_velocity=9<ref name=ayres2018/>
| rotation={{val|298|u=days|p=≥}}<ref name=Testa2004/>
| luminosity=10,700<ref name=vlti/>
| temperature=7,400<ref name=ayres2018>{{cite journal |bibcode=2018ApJ...854...95A |title=Cracking the Conundrum of F-supergiant Coronae |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |year=2018 |volume=854 |issue=2 |page=95 |doi=10.3847/1538-4357/aaa6d7 |arxiv=1802.02552 |s2cid=119101035 }}</ref>
| age_myr = {{val|25.1|2.5}}<ref name=Tetzlaff2011>{{cite journal | title=A catalogue of young runaway Hipparcos stars within 3 kpc from the Sun | last1=Tetzlaff | first1=N. | last2=Neuhäuser | first2=R. | last3=Hohle | first3=M. M. | journal=Monthly Notices of the Royal Astronomical Society | volume=410 | issue=1 | pages=190–200 | date=January 2011 | doi=10.1111/j.1365-2966.2010.17434.x | arxiv=1007.4883 | bibcode=2011MNRAS.410..190T | s2cid=118629873 }}</ref>
}}
{{Starbox catalog
| names={{odlist | name=Suhayl | name2=Suhel | name3=Suhail | B=α Carinae | CPD=−52°1941 | FK5=245 | HD=45348 | HIP=30438 | HR=2326 | SAO=234480| GC=8302 }}<ref name=SIMBAD>{{cite simbad | title=alf Car | access-date=2019-03-09 }}</ref>
}}
{{Starbox reference
| Simbad=canopus
}}
{{Starbox end}}
'''Canopus''' is the brightest star in the southern [[constellation]] of [[Carina (constellation)|Carina]] and the [[list of brightest stars|second-brightest star]] in the [[night sky]]. It is also [[Bayer designation|designated]] '''α Carinae''', which is [[Latinisation of names|Latinised]] to '''Alpha Carinae'''. With a [[visual apparent magnitude]] of −0.74, it is outshone only by [[Sirius]]. Located around {{val|310|ul=light-years}} from the [[Sun]], Canopus is a [[bright giant]] of [[spectral type A9]], so it is essentially white when seen with the naked eye. It has a luminosity over 10,000 times the [[luminosity of the Sun]], is eight times as [[mass of the Sun|massive]], and has expanded to 71 times the [[Sun's radius]]. Its enlarged [[photosphere]] has an [[effective temperature]] of around {{val|7,400|fmt=commas|u=K}}. Canopus is undergoing [[stellar core|core]] [[helium fusion|helium burning]] and is currently in the so-called [[blue loop]] phase of its [[stellar evolution|evolution]], having already passed through the [[red-giant branch]] after exhausting the hydrogen in its core. Canopus is a [[X-ray astronomy|source of X-rays]], which are likely being emitted from its [[stellar corona|corona]].
The prominent appearance of Canopus means it has been the subject of mythological lore among many ancient peoples. Its proper name is generally considered to originate from the [[Greek mythology|mythological]] [[Canopus (mythology)|Canopus]], who was a navigator for [[Menelaus]], king of [[Sparta]]. The [[acronychal rising]] marked the date of the Ptolemaia festival in Egypt. In ancient India, it was named [[Agastya]] after the revered [[Vedas|Vedic]] sage. For Chinese astronomers, it was known as the [[Old Man of the South Pole]].
==Nomenclature==
The name ''Canopus'' is a Latinisation of the [[Ancient Greek]] name Κάνωβος/Kanôbos, recorded in Claudius Ptolemy's ''[[Almagest]]'' (c.150 AD). Eratosthenes used the same spelling.<ref name="ridpathCr"/> Hipparchos wrote it as Κάνωπος. [[John Flamsteed]] wrote Canobus,<ref>{{cite book|last=Flamsteed|first=John|title=Atlas coelestis|location=London, United Kingdom|date=1729|pages=Constellation Map of Southern Hemisphere|url=http://lhldigital.lindahall.org/u?/astro_atlas,1191}}</ref> as did [[Edmond Halley]] in his 1679 ''Catalogus Stellarum Australium''.<ref name="Halley 1679">{{cite book|last=Halley|first=Edmond|title=Catalogus stellarum australium; sive, Supplementum catalogi Tychenici, exhibens longitudines et latitudines stellarum fixarum, quae, prope polum Antarcticum sitae, in horizonte Uraniburgico Tychoni inconspicuae fuere, accurato calculo ex distantiis supputatas, & ad annum 1677 completum correctas...Accedit appendicula de rebus quibusdam astronomicis|publisher=T. James|location=London|date=1679|pages=30|url=http://babel.hathitrust.org/cgi/pt?id=mdp.39015007000170;view=1up;seq=41;size=150}}</ref> The name has two possible derivations, both listed in [[Richard Hinckley Allen]]'s seminal ''[[Star Names: Their Lore and Meaning]]''.
* [[Argo Navis]] was the ship used by [[Jason]] and the Argonauts in the legend of the [[Trojan War]]. The brightest star in the constellation was given the name of a ship's pilot from another Greek legend: [[Canopus (mythology)|Canopus]], pilot of [[Menelaus]]' ship on his quest to retrieve [[Helen of Troy]] after she was taken by [[Paris (mythology)|Paris]].<ref name="hinkley63">{{cite book|first=Richard Hinckley|last=Allen|author-link=Richard Hinckley Allen|date=1963|orig-year=1899|title=Star Names: Their Lore and Meaning|pages=[https://archive.org/details/starnamestheirlo00alle/page/67 67–72]|edition=Revised|publisher=Dover Publications|location=New York|isbn=0-486-21079-0|url-access=registration|url=https://archive.org/details/starnamestheirlo00alle/page/67}}</ref>
* A ruined ancient Egyptian port named [[Canopus, Egypt|Canopus]] lies near the mouth of the [[Nile]], site of the [[Battle of the Nile]]. It is speculated that its name is derived from the Egyptian [[Coptic language|Coptic]] ''Kahi Nub'' ("Golden Earth"), which refers to how Canopus would have appeared near the horizon in [[ancient Egypt]], reddened by atmospheric extinction from that position.<ref name="hinkley63"/><ref name=lynn1905>{{cite journal |bibcode=1905Obs....28..289L |title=The brightest fixed star and its name |last1=Lynn |first1=W. T. |journal=The Observatory |year=1905 |volume=28 |page=289 }}</ref>
In 2016, the [[International Astronomical Union]] organized a [[IAU Working Group on Star Names|Working Group on Star Names]] (WGSN) to catalog and standardize proper names for stars.<ref name="WGSN">{{cite web | url=https://www.iau.org/science/scientific_bodies/working_groups/280/ | title=IAU Working Group on Star Names (WGSN) | website=iau.org | publisher=[[International Astronomical Union]] | access-date=22 May 2016}}</ref> The WGSN's first bulletin of July 2016 included a table of the first two batches of names approved by the WGSN, which included ''Canopus'' for this star.<ref name="WGSN1">{{cite web | url=https://www.iau.org/static/science/scientific_bodies/working_groups/280/WGSN_bulletin1.pdf | title=Bulletin of the IAU Working Group on Star Names, No. 1 | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06 }}</ref> Canopus is now included in the ''IAU Catalog of Star Names''.<ref name="IAU-CSN">{{cite web | url=https://www.iau.org/public/themes/naming_stars/ | title=IAU Catalog of Star Names | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06}}</ref>
Canopus traditionally marked the rudder of the ship [[Argo Navis]].<ref>{{cite journal | title = On Frederick de Houtman's Catalogue of Southern Stars, and the Origin of the Southern Constellations | last1= Knobel|first1=E. B. |journal = [[Monthly Notices of the Royal Astronomical Society]] | volume= 77| issue= 5 | pages=414–432 [422] | bibcode = 1917MNRAS..77..414K |date=1917 | doi=10.1093/mnras/77.5.414| doi-access=free }}</ref> German celestial cartographer [[Johann Bayer]] gave it—as the brightest star in the constellation—the [[Bayer designation|designation]] of ''α Argus'' ([[Latinisation of names|Latinised]] to ''Alpha Argus'') in 1603. In 1763, French astronomer [[Nicolas Louis de Lacaille]] divided the huge constellation into three smaller ones,<ref name=Glass2012>{{cite book | title=Nicolas-Louis De La Caille, Astronomer and Geodesist | first=Ian Stewart | last=Glass | date=November 17, 2012 | page=73 | isbn=9780191649608 | publisher=OUP Oxford | url=https://www.google.com/books/edition/Nicolas_Louis_De_La_Caille_Astronomer_an/eZjlHAIBeRAC?hl=en&gbpv=1&pg=PT73 }}</ref> and hence Canopus became ''α Carinae'' ([[Latinisation of names|Latinised]] to ''Alpha Carinae''). It is listed in the [[Bright Star Catalogue]] as HR 2326, the [[Henry Draper Catalogue]] as HD 45348, and the [[Hipparcos catalogue]] as HIP 30438.<ref name=SIMBAD/> Flamsteed did not number this southern star, but [[Benjamin Apthorp Gould]] gave it the number 7 (7 G. Carinae) in his ''Uranometria Argentina''.<ref name=Gould1878>{{cite journal | title=Uranometria Argentina: Brightness and position of every fixed star, down to the seventh magnitude, within one hundred degrees of the South Pole; with atlas | last=Gould | first=Benjamin Apthorp | journal=Resultados del Observatorio Nacional Argentino | volume=1 | page=140 | date=1878 | bibcode=1879RNAO....1....1G }}</ref>
An occasional name seen in English is ''Soheil'', or the feminine Soheila; in Turkish is ''Süheyl'', or the feminine Süheyla, from the Arabic name for several bright stars, سهيل ''suhayl'',<ref name="hinkley63"/> and Canopus was known as Suhel {{IPAc-en|'|s|uː|h|E|l}} in medieval times.<ref name=kunitzsch/> Alternative spellings include Suhail, Souhail, Suhilon, Suheyl, Sohayl, Suhayil, Shoel, Sohil, Soheil, Sahil, Suhayeel, Sohayil, Sihel, and Sihil.<ref name="hinkley63"/> An alternative name was ''Wazn'' "weight" or ''Haḍar'' "ground", possibly related to its low position near the horizon.<ref name="hinkley63"/> Hence comes its name in the ''[[Alfonsine tables]]'', Suhel ponderosus, a Latinization of ''Al Suhayl al Wazn''.<ref name="hinkley63"/> Its Greek name was revived during the [[Renaissance]].<ref name=kunitzsch>{{cite book |last1=Kunitzsch|first1=Paul |last2=Smart|first2=Tim |date = 2006|title = A Dictionary of Modern star Names: A Short Guide to 254 Star Names and Their Derivations |edition = 2nd rev. |publisher = Sky Publishing Corporation |location = Cambridge, Massachusetts |isbn = 978-1-931559-44-7 |page = 23}}</ref>
==Observation==
[[File:Carina constellation map.svg|thumb|left|The constellation [[Carina (constellation)|Carina]] with Canopus towards the right (west)]]
The Spanish Muslim astronomer [[Ibn Rushd]] went to [[Marrakesh]] (in Morocco) to observe the star in 1153, as it was invisible in his native [[Córdoba, Spain|Córdoba]], [[Al-Andalus]]. He used the different visibility in different latitudes to argue that the [[Spherical Earth|earth is round]], following [[Spherical Earth#Aristotle|Aristotle's argument]] which held that such an observation was only possible if the earth was a relatively small sphere.<ref name=ibn_rushd>{{cite encyclopedia|first1=Juan|last1=Vernet|author-link1=Juan Vernet|first2=Julio|last2=Samsó|author-link2=Julio Samsó |title=The development of Arabic science in Andalusia |page=264|editor=[[Roshdi Rashed]]|encyclopedia=Encyclopedia of the History of Arabic Science | date=1996|publisher=Routledge|isbn=978-0-415-12410-2|oclc=912501823}}</ref>
English explorer [[Robert Hues]] brought Canopus to the attention of European observers in his 1592 work ''Tractatus de Globis'', along with [[Achernar]] and [[Alpha Centauri]], noting:<blockquote>"Now, therefore, there are but three [[First-magnitude star|Stars of the first magnitude]] that I could perceive in all those parts which are never seene here in England. The first of these is that bright Star in the sterne of [[Argo Navis|Argo]] which they call Canobus. The second is in the end of [[Eridanus (constellation)|Eridanus]]. The third is in the right foote of the [[Centaurus|Centaure]]."<ref>Knobel, p. 416.</ref></blockquote>
[[File:Vela and Surrounding Constellations (ground-based image).jpg|right|thumb|Wide angle view showing Canopus and other prominent stars with the Milky Way|alt=A field of stars against the Milky Way background with the prominent stars and constellations labelled]]
In the [[Southern Hemisphere]], Canopus and [[Sirius]] are both visible high in the sky simultaneously, and reach a [[meridian (astronomy)|meridian]] just {{val|21|u=minutes}} apart. Brighter than [[first-magnitude star|first magnitude]], Canopus can be seen by naked eye in the early twilight. Mostly visible in mid to late summer in the Southern Hemisphere, Canopus [[Culmination|culminates]] at midnight on December 27,<ref name="motz" /> and at 9 PM on February 11.<ref name="Schaaf257">Schaaf, p. 257.</ref>
When seen from latitudes south of {{DEC|37|18}} S, Canopus is a [[circumpolar star]]. Since Canopus is so far south in the sky, it never rises in mid- to far-northern latitudes; in theory the northern limit of visibility is latitude {{DEC|37|18}} north. This is just south of [[Athens]], [[Richmond, Virginia]] (USA), and [[San Francisco]], and very close to [[Seville]] and [[Agrigento]]. It is almost exactly the latitude of [[Lick Observatory]] on [[Mount Hamilton (California)|Mt. Hamilton, California]], from which it is readily visible because of the effects of elevation and [[atmospheric refraction]], which add another degree to its apparent altitude. Under ideal conditions, it can be spotted as far north as latitude {{DEC|37|31}} from the Pacific coast.<ref>D. Gieringer, "Exploring the Tropic of Canopus", ''Astronomy'', December 1985, p.24.</ref> Another northernmost record of visibility came from [[Mount Nemrut]] in Turkey, latitude {{DEC|37|59}}.<ref>{{cite web |last1=Tezel |first1=Tunç |author-link=Tunç Tezel |url=http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |title=Zodiacal Light and Nemrut Heritage |work=The World At Night (TWAN) |access-date=17 March 2014 |date=8 Oct 2013 |archive-url=https://web.archive.org/web/20140317134955/http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |archive-date=17 March 2014 |url-status=dead }}</ref> It is more easily visible in places such as the Gulf Coast and Florida, and the island of [[Crete]] (Greece) where the best season for viewing it around 9 p.m. is during late January and early February.<ref name="motz">{{cite book|last1=Motz|first1=Lloyd|last2=Nathanson|first2=Carol|title=The Constellations: An Enthusiast's Guide to the Night Sky|publisher=Aurum Press|location=London, United Kingdom|date=1991|pages=376–77|isbn=1-85410-088-2}}</ref>
Canopus has a B–V [[color index]] of +0.15—where 0 is a blue-white—indicating it is essentially white, although it has been described as yellow-white. Canopus' spectral type has been given as F0 and the incrementally warmer A9. It is less yellow than [[Altair]] or [[Procyon]], with indices measured as 0.22 and 0.42, respectively.<ref name=Hoffleit1991>{{cite book | title=Bright Star Catalogue | edition=5th Revised | last1=Hoffleit | first1=D. | last2=Warren Jr. | first2=W. H. | date=1991 | publisher=[[Centre de Données astronomiques de Strasbourg|CDS]] }}</ref> Some observers may have perceived Canopus as yellow-tinged because it is low in the sky and hence subject to atmospheric effects.<ref name="Schaaf112">Schaaf, pp. 112–13.</ref> [[Patrick Moore]] said that it never appeared anything but white to him.<ref name="moore2000">{{cite book | first1=Patrick | last1=Moore | title=Exploring the night sky with binoculars | edition=4th | publisher=Cambridge University Press | year=2000 | isbn=9780521793902 | page=[https://archive.org/details/exploringnightsk00moor/page/69 69] | url=https://archive.org/details/exploringnightsk00moor| url-access=registration }}</ref> The [[bolometric correction]] for Canopus is 0.00,<ref name=smiljanic2006/> indicating that the visual [[absolute magnitude]] and bolometric absolute magnitude are equal.
Canopus was previously proposed to be a member of the [[Scorpius–Centaurus association]], however it is not located near the subgroups of that association, and has not been included as a Sco-Cen member in kinematic studies that used [[Hipparcos]] astrometric data.<ref name="deZeeuw">{{cite journal|last1=de Zeeuw|first1=P.T. |last2=Hoogerwerf|first2=R. |last3=de Bruijne|first3=J.H.J |last4=Brown|first4=A.G.A |last5=Blaauw|first5=A. |date=1999|title=A HIPPARCOS Census of the Nearby OB Associations |journal=The Astronomical Journal |volume=117 |issue=1 |pages=354–399|bibcode=1999AJ....117..354D |doi=10.1086/300682|arxiv = astro-ph/9809227 |s2cid=16098861 }}</ref> Canopus is not thought to be a member of any nearby young stellar groups.<ref name=mamajek>{{cite journal | url=https://figshare.com/articles/Canopus_B_A_Candidate_Common_Proper_Motion_Companion_to_the_Second_Brightest_Star/1132696 | title=Canopus B: A Candidate Common Proper Motion Companion to the Second Brightest Star | last=Mamajek | first=Eric | year=2014 | publisher=Figshare | doi=10.6084/m9.figshare.1132696.v3 | access-date=2020-09-10 }}</ref> In 2014, astronomer Eric Mamajek reported that an extremely magnetically active M dwarf (having strong coronal X-ray emission), 1.16 degrees south of Canopus, appears to share a [[common proper motion]] with Canopus. The projected separation of the M dwarf 2MASS J06234738-5351131 ("Canopus B") is approximately 1.9 parsecs. However, despite this large separation, it is still within the estimated tidal radius (2.9 parsecs) for the massive star Canopus.<ref name="mamajek"/>
No star closer than Canopus is more luminous than it, and it has been the brightest star in Earth's night sky during three epochs over the past four million years. Other stars appear brighter only during relatively temporary periods, during which they are passing the Solar System much closer than Canopus. About 90,000 years ago, [[Sirius]] moved close enough that it became brighter than Canopus, and that will remain so for another 210,000 years. But in 480,000 years, as Sirius moves further away and appears fainter, Canopus will once again be the brightest, and will remain so for a period of about 510,000 years.<ref name="tomkin98">{{cite journal|last=Tomkin|first=Jocelyn|date=April 1998|title=Once and Future Celestial Kings|journal=Sky and Telescope|volume=95|issue=4|pages=59–63|bibcode=1998S&T....95d..59T}}</ref><!-- this all comes from same paper -->
===Role in navigation===
The southeastern wall of the [[Kaaba]] in [[Mecca]] is aligned with the rising point of Canopus, and is also named ''Janūb''.<ref>{{cite book|author=George Nicholas Atiyeh|title=The Book in the Islamic World: The Written Word and Communication in the Middle East|url=https://books.google.com/books?id=t4LEfpCW_kQC|date=1 January 1995|publisher=SUNY Press|isbn=978-0-7914-2473-5}}</ref> The [[Negev Bedouin|Bedouin]] people of the [[Negev]] and [[Sinai Peninsula|Sinai]] knew Canopus as ''Suhayl'', and used it and [[Polaris]] as the two principal stars for navigation at night. Because it disappears below the horizon in those regions, it became associated with a changeable nature, as opposed to always-visible Polaris, which was circumpolar and hence 'steadfast'.<ref>{{cite journal |last=Bailey |first=Clinton |date=1974 |title=Bedouin Star-Lore in Sinai and the Negev |journal=Bulletin of the School of Oriental and African Studies, University of London |volume=37 |issue=3 |pages=580–96 |type=abstract |doi=10.1017/S0041977X00127491 |jstor=613801|s2cid=131527348 }}</ref>
The south [[celestial pole]] can be approximately located using Canopus and another bright star, [[Achernar]], as the three make an [[equilateral triangle]]. Canopus sits on an imaginary line that extends {{DEC|36}} one way to Sirius and {{DEC|37}} to the south celestial pole.<ref>{{Cite book| last1 = Heifetz| first1 = Milton| last2 = Tirion| first2 = Wil| title = A Walk Through the Heavens: A Guide to Stars and Constellations and Their Legends | date = 2007| publisher = [[Cambridge University Press]]| location = Cambridge | page = 38 | isbn=978-1-139-46138-2}}</ref>
Canopus's brightness and location well off the [[ecliptic]] make it useful for space navigation. Many spacecraft carry a special camera known as a "Canopus [[star tracker|Star Tracker]]" plus a Sun sensor for [[Orientation (geometry)|attitude]] determination. [[Mariner 4]] used Canopus for [[Spin-stabilisation|second axis stabilisation]] (after locking on the Sun) in 1964, the first time a star had been used.<ref>{{cite book |last1=United States. National Aeronautics and Space Administration. Scientific and Technical Information Division |title=Astronautics and Aeronautics, 1964: Chronology on Science, Technology and Policy |date=1965 |publisher=Scientific and Technical Information Division, National Aeronautics and Space Administration |page=398 |url=https://books.google.com/books?id=ckkCAAAAIAAJ&pg=PA398}}</ref>
==Spectrum==
Canopus was little-studied by western scientists before the 20th century. It was given a spectral class of F in 1897, an early use of this extension to [[Secchi class]] I, applied to those stars where the hydrogen lines are relatively weak and the [[calcium K line]] relatively strong.<ref>{{cite journal |bibcode=1897ApJ.....6..349P |title=Spectra of bright southern stars |last1=Pickering |first1=E. C. |last2=Cannon |first2=A. J. |journal=The Astrophysical Journal |year=1897 |volume=6 |page=349 |doi=10.1086/140407 }}</ref> It was given as a standard star of F0 in the [[Henry Draper Catalogue]], with the spectral type F0 described as having hydrogen lines half the strength of an A0 star and the calcium K line three times as strong as Hδ.<ref name=hd>{{cite journal |bibcode=1918AnHar..92....1C |title=The Henry Draper catalogue : 4h, 5h and 6h |last1=Cannon |first1=Annie Jump |last2=Pickering |first2=Edward Charles |journal=Annals of Harvard College Observatory |year=1918 |volume=92 |page=1 }}</ref> American astronomer [[Jesse L. Greenstein|Jesse Greenstein]] was interested in stellar spectra and used the newly built [[Otto Struve Telescope]] at [[McDonald Observatory]] to analyze the star's spectrum in detail.<ref>{{cite book |last1=Trimble |first1=Virginia | first2= Thomas R. |last2=Williams | first3= Katherine | last3=Bracher| first4= Richard | last4=Jarrell| first5=Jordan D.| last5= Marché| first6=F. Jamil | last6=Ragep |title=Biographical Encyclopedia of Astronomers |date=2007 |publisher=Springer Science & Business Media |location=New York, New York |isbn=978-0-387-30400-7 |page=438 |url=https://books.google.com/books?id=t-BF1CHkc50C&pg=PA438}}</ref> In a 1942 paper, he reported that the spectrum is dominated by strong broad hydrogen lines. There are also [[absorption line]]s of carbon, nitrogen, oxygen, sulphur, iron, and many ionised metals.<ref name=greenstein1942>{{cite journal |bibcode=1942ApJ....95..161G |title=The Spectrum of α Carinae |last1=Greenstein |first1=Jesse L. |journal=The Astrophysical Journal |year=1942 |volume=95 |page=161 |doi=10.1086/144382 }}</ref> It was studied in the [[ultraviolet]] by an early astronomical satellite, [[Gemini XI]] in 1966. The UV spectra were considered to be consistent with an F0 [[Supergiant star|supergiant]] having a temperature of {{val|6,900|fmt=commas|u=K}}, the accepted parameters for Canopus at the time.<ref name=kondo1970>{{cite journal |bibcode=1970ApJ...159..927K |title=Ultraviolet Spectrophotometry of Canopus from Gemini XI |last1=Kondo |first1=Y. |last2=Henize |first2=K. G. |last3=Kotila |first3=C. L. |journal=The Astrophysical Journal |year=1970 |volume=159 |page=927 |doi=10.1086/150370 }}</ref> New Zealand-based astronomers [[John Hearnshaw]] and Krishna Desikachary examined the spectrum in greater detail, publishing their results in 1982.<ref>{{cite journal |title=The spectrum of Canopus | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 198 | year= 1982 | issue= 2 | pages= 311–320 | doi= 10.1093/mnras/198.2.311 | bibcode=1982MNRAS.198..311H| doi-access= free }}</ref><ref>{{cite journal |title=The spectrum of Canopus II - Analysis and composition | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 201 | year= 1982 | issue= 3 | pages= 707–721 | doi= 10.1093/mnras/201.3.707 | bibcode=1982MNRAS.201..707D| doi-access= free }}</ref>
When [[luminosity class]]es were added to the MK spectral classification scheme, Canopus was assigned class Iab indicating an intermediate luminosity supergiant. This was based on the relative strengths of certain spectral lines understood to be sensitive to the luminosity of a star.<ref name=devaucoleurs>{{cite journal|title=Spectral types and luminosities of B, A and F southern stars|author=de Vaucouleurs, A.|journal=Monthly Notices of the Royal Astronomical Society|volume=117|page=449|date=1957|issue=4|bibcode=1957MNRAS.117..449D|doi=10.1093/mnras/117.4.449|doi-access=free}}</ref> In the [[Bright Star Catalogue]] 5th edition it is given the spectral class F0II, the luminosity class indicating a [[bright giant]].<ref name=bsc>{{cite book |bibcode=1991bsc..book.....H |year=1991 |title=The Bright star catalogue |last1=Hoffleit |first1=Dorrit |last2=Jaschek |first2=Carlos }}</ref> [[Balmer line]] profiles and oxygen line strengths indicate the size and luminosity of Canopus.<ref name=kovtyukh2012>{{cite journal |bibcode=2012MNRAS.423.3268K |title=Accurate luminosities from the oxygen λ7771-4 Å triplet and the fundamental parameters of F-G supergiants |last1=Kovtyukh |first1=V. V. |last2=Gorlova |first2=N. I. |last3=Belik |first3=S. I. |journal=Monthly Notices of the Royal Astronomical Society |year=2012 |volume=423 |issue=4 |page=3268 |doi=10.1111/j.1365-2966.2012.21117.x |arxiv=1204.4115 |s2cid=118683158 }}</ref>
When the effects of stellar rotation speed on spectral lines are accounted for, the MK spectral class of Canopus is adjusted to A9II.<ref name=perkins/> Its spectrum consists mostly of absorption lines on a visible [[continuous spectrum|continuum]], but some emission has been detected. For example, the [[calcium K line]] have weak emission wings on each side of the strong central absorption line, first observed in 1966. The emission line profiles are usually correlated with the luminosity of the star as described by the [[Wilson-Bappu effect]], but in the case of Canopus they indicate a luminosity much lower than that calculated by other methods.<ref name=warner1966>{{cite journal|title=CA II emission in the spectrum of Canopus|journal=The Observatory |volume=86 |pages=82|date=April 1966|last=Warner |first=B. |bibcode=1966Obs....86...82W }}</ref> More detailed observations have shown that the emission line profiles are variable and may be due to [[plage (astronomy)|plage]] areas on the surface of the star. Emission can also be found in other lines such as the h and k lines of ionised magnesium.<ref name=bappu1984>{{cite journal |bibcode=1984BASI...12..196B |title=CA II K emission in Canopus |last1=Bappu |first1=M. K. V. |last2=Mekkaden |first2=M. V. |last3=Rao |first3=N. K. |journal=Bulletin of the Astronomical Society of India |year=1984 |volume=12 |page=196 }}</ref>
==Distance==
Before the launch of the [[Hipparcos]] satellite telescope, distance estimates for Canopus varied widely, from 96 [[light-year]]s to 1200 light-years. The closer distance was derived from parallax measurements of around {{val|33|ul=mas}}.<ref name=vandekamp1943>{{cite journal |title=Note on the Parallax of Canopus|journal=Popular Astronomy |volume=51 |date=1943 |page=172 |last=van de Kamp |first=Peter|bibcode=1943PA.....51..172V }}</ref> The larger distance derives from the assumption of a very bright [[absolute magnitude]] for Canopus.<ref name=vanzyl>{{cite book|author=J.E. van Zyl|title=Unveiling the Universe: An Introduction to Astronomy|url=https://books.google.com/books?id=Cj7uBwAAQBAJ&pg=PA184|date=6 December 2012|publisher=Springer Science & Business Media|isbn=978-1-4471-1037-8|pages=184–}}</ref>
Hipparcos established Canopus as being {{val|310|u=light-years}} ({{val|95|ul=parsecs}}) from the [[Solar System]]; this is based on its 2007 [[parallax]] measurement of {{Val|10.43|0.53|ul=mas}}.<ref name="van Leeuwen2007"/> At 95 parsecs, the [[interstellar extinction]] for Canopus is low at 0.26 magnitudes.<ref name=DomicianoDeSouza/> Canopus is too bright to be included in the normal observation runs of the [[Gaia satellite]] and there is no published Gaia parallax for it.<ref name=dr2>{{cite DR2}}</ref>
At present the star is drifting further away from the Sun with a [[radial velocity]] of 20 km/s. Some 3.1 million years ago it made the closest approach to the Sun at a distance of about {{convert|52.87|pc|ly|0|adj=ri0|order=flip|abbr=on|lk=off}}. Canopus is orbiting the Milky Way with a heliocentric velocity of 24.5 km/s and a low [[orbital eccentricity|eccentricity]] of 0.065.<ref name=Anderson2012>{{citation | last1=Anderson | first1=E. | last2=Francis | first2=Ch. | title=XHIP: An extended hipparcos compilation | journal=Astronomy Letters | volume=38 | issue=5 | pages=331 | year=2012 | bibcode=2012AstL...38..331A | arxiv=1108.4971 | doi=10.1134/S1063773712050015 | s2cid=119257644 | postscript=. }}</ref>
==Physical characteristics==
[[File:Constellation_Carina.jpg|thumb|right|upright|Canopus is the brightest star in the constellation of Carina (top).]]
The [[absorption line]]s in the spectrum of Canopus shift slightly with a period of {{val|6.9|u=days}}. This was first detected in 1906 and the [[doppler effect|Doppler]] variations were interpreted as orbital motion.<ref name=curtis1907>{{cite journal |bibcode=1907PASP...19R.259C |title=The orbits of the spectroscopic binaries alpha Carinae, kappa Velorum, and alpha Pavonis |last1=Curtis |first1=H. D. |journal=Publications of the Astronomical Society of the Pacific |year=1907 |volume=19 |page=259 |doi=10.1086/121781 }}</ref> An orbit was even calculated, but no such companion exists and the small radial velocity changes are due to movements in the atmosphere of the star. The maximum observed [[radial velocities]] are only 0.7 to {{val|1.6|ul=km/s}}. Canopus also has a magnetic field that varies with the same period, detected by the [[Zeeman splitting]] of its spectral lines.<ref name=weiss1986>{{cite journal |bibcode=1986A&A...160..243W | title=The magnetic field of Canopus | last=Weiss | first=W. W. | journal= Astronomy and Astrophysics |volume= 160|pages= 243–250 | year=1986}}</ref> Canopus is bright at [[microwave]] wavelengths, one of the few F-class stars to be detected by radio.<ref name=gudel2002>{{cite journal |bibcode=2002ARA&A..40..217G |title=Stellar Radio Astronomy: Probing Stellar Atmospheres from Protostars to Giants |last1=Güdel |first1=Manuel |journal=Annual Review of Astronomy and Astrophysics |year=2002 |volume=40 |pages=217–261 |doi=10.1146/annurev.astro.40.060401.093806 |arxiv=astro-ph/0206436 |s2cid=53633983 }}</ref> The [[rotation period]] of the star is not accurately known, but may be over three hundred days.<ref name=Testa2004>{{cite journal | title=The Density of Coronal Plasma in Active Stellar Coronae | last1=Testa | first1=Paola | last2=Drake | first2=Jeremy J. | last3=Peres | first3=Giovanni | journal=The Astrophysical Journal | volume=617 | issue=1 | pages=508–530 | date=December 2004 | doi=10.1086/422355 | arxiv=astro-ph/0405019 | bibcode=2004ApJ...617..508T | s2cid=17532089 }}</ref> The [[projected rotational velocity]] has been measured at 9 km/s.<ref name=ayres2018/>
An early [[Interferometry|interferometric]] measurement of its [[angular diameter]] in 1968 gave a [[Limb darkening|limb-darkened]] value of {{val|6.86|ul=mas}}, close to the accepted modern value.<ref>{{cite journal |bibcode=1968ARA&A...6...13B |title=Measurement of Stellar Diameters |last1=Brown |first1=R. Hanbury |journal=Annual Review of Astronomy and Astrophysics |year=1968 |volume=6 |page=13 |doi=10.1146/annurev.aa.06.090168.000305 }}</ref> [[Very-long-baseline interferometry]] has been used to calculate Canopus' angular diameter at {{val|6.9|ul=mas}}. Combined with distance calculated from its Hipparcos parallax, this gives it a radius of 71 times [[Solar radius|that of the Sun]].<ref name=vlti/> If it were at the centre of the Solar System, it would extend 90% of the way to the orbit of [[Mercury (planet)|Mercury]].<ref name=Kalerstars>{{cite web|url=http://stars.astro.illinois.edu/sow/canopus.html|title=Canopus|last=Kaler|first=Jim|work=Stars|publisher=University of Illinois|access-date=8 July 2012|date=26 June 2009}}</ref> The radius and temperature relative to the Sun means that it is 10,700 times more luminous than the Sun, and its position in the [[H-R diagram]] relative to theoretical [[stellar evolution|evolutionary]] tracks means that it is {{Val|8.0|0.3}} times as massive as the Sun.<ref name=vlti/> Measurements of its shape find a 1.1° departure from spherical symmetry.<ref name=cruzalebes2015>{{cite journal |bibcode=2015MNRAS.446.3277C |title=Departure from centrosymmetry of red giants and supergiants measured with VLTI/AMBER |last1=Cruzalèbes |first1=P. |last2=Jorissen |first2=A. |last3=Chiavassa |first3=A. |last4=Paladini |first4=C. |last5=Rabbia |first5=Y. |last6=Spang |first6=A. |journal=Monthly Notices of the Royal Astronomical Society |year=2015 |volume=446 |issue=4 |page=3277 |doi=10.1093/mnras/stu2382 |doi-access=free }}</ref>
Canopus is a source of [[X-ray astronomy|X-rays]], which are probably produced by its corona, magnetically heated to several million [[Kelvin]]. The temperature has likely been stimulated by fast rotation combined with strong convection percolating through the star's outer layers.<ref name=ness>{{cite journal|bibcode=2004A&A...427..667N|title=On the sizes of stellar X-ray coronae|journal=Astronomy and Astrophysics|volume=427|issue=2|pages=667–683|last1=Ness|first1=J.-U.|last2=Güdel|first2=M.|last3=Schmitt|first3=J. H. M. M.|last4=Audard|first4=M.|last5=Telleschi|first5=A.|year=2004|doi=10.1051/0004-6361:20040504|arxiv = astro-ph/0407231 |s2cid=11468731}}</ref> The soft X-ray sub-coronal X-ray emission is much weaker than the hard X-ray coronal emission. The same behaviour has been measured in other F-class supergiants such as [[α Persei]] and is now believed to be a normal property of such stars.<ref name=ayres2018/>
== Evolution ==
The spectrum of Canopus indicates that it has exhausted its core hydrogen and [[stellar evolution|evolved]] away from the [[main sequence]], where it spent some 30 million years of its existence as a blue-white star <!-- source suggests B2V but may be too exact --> of around 10 solar masses.<ref>{{cite journal |last1=Peimbert |first1=M. |last2=Wallerstein | first2= G.| last3= Pilachowski | first3= C. A. |title=An upper limit for the deuterium abundance in Canopus |journal=Astronomy and Astrophysics |date=1981 |volume=104 |issue=1 |pages=72–74 | bibcode=1981A&A...104...72P}}</ref> The position of Canopus in the [[H–R diagram]] indicates that it is currently in the core-helium burning phase.<ref name=vlti/> It is an intermediate mass star that has left the [[red-giant branch]] before its core became [[degenerate matter|degenerate]] and is now in a [[blue loop]].<ref name=desouza>{{Cite journal | last1 = Domiciano De Souza | first1 = A. | last2 = Bendjoya | first2 = P. | last3 = Vakili | first3 = F. | last4 = Millour | first4 = F. | last5 = Petrov | first5 = R. G. | title = Diameter and photospheric structures of Canopus from AMBER/VLTI interferometry | doi = 10.1051/0004-6361:200810450 | journal = Astronomy and Astrophysics | volume = 489 | issue = 2 | pages = L5–L8 | year = 2008 |bibcode = 2008A&A...489L...5D | url = https://hal.archives-ouvertes.fr/hal-00316994/document | doi-access = free }}</ref> Models of stellar evolution in the blue loop phase show that the length of the blue loop is strongly affected by rotation and mixing effects inside the star. It is difficult to determine whether a star is currently evolving towards hotter temperature or returning to cooler temperatures, since the evolutionary tracks for stars with different masses overlap during the blue loops.<ref name=smiljanic2006>{{cite journal |bibcode=2006A&A...449..655S |title=CNO in evolved intermediate mass stars |last1=Smiljanic |first1=R. |last2=Barbuy |first2=B. |last3=De Medeiros |first3=J. R. |last4=Maeder |first4=A. |journal=Astronomy and Astrophysics |year=2006 |volume=449 |issue=2 |page=655 |doi=10.1051/0004-6361:20054377 |arxiv=astro-ph/0511329 |s2cid=3711409 }}</ref>
Canopus lies on the warm side of the [[instability strip]] and does not pulsate like [[Cepheid variables]] of a similar luminosity.<ref name=ayres2011>{{cite journal |doi=10.1088/0004-637X/738/2/120 |title=The Curious Case of the Alpha Persei Corona: A Dwarf in Supergiant's Clothing? |year=2011 |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |volume=738 |issue=2 |page=120 |bibcode=2011ApJ...738..120A |doi-access=free }}</ref> However its atmosphere does appear to be unstable, showing strong signs of convection.<ref name=smiljanic2006/>
Canopus may not be massive enough for its [[nuclear fusion|fusion]] chain to reach iron and trigger a core collapse and subsequent [[supernova]], instead eventually becoming a neon-oxygen [[white dwarf]].<ref name=Kalerstars/>
==Cultural significance ==
Canopus was known to the ancient Mesopotamians and given the name ''NUN-ki'' and represented the city of [[Eridu]] in the ''Three Stars Each'' [[Babylonian star catalogues]] and later [[MUL.APIN]] around 1100 BC.<ref>{{cite journal | last = Rogers | first = John H. | date = 1998 | title = Origins of the Ancient Constellations: I. The Mesopotamian Traditions | journal = Journal of the British Astronomical Association | volume = 108 | issue = 1 | pages = 9–28 | bibcode = 1998JBAA..108....9R}}</ref> Today, the star [[Sigma Sagittarii]] is known by the common name Nunki.<ref name=allen>{{citation | page=359 | first1=Richard Hinckley | last1=Allen | title=Star Names, their lore and meaning}}</ref>
Canopus was not visible to the mainland [[Ancient Greece|ancient Greeks]] and [[Roman Empire|Romans]]; it was, however, visible to the [[ancient Egypt]]ians.<ref name="Schaaf107">Schaaf, p. 107.</ref> Hence [[Aratus]] did not write of the star as it remained below the horizon, while [[Eratosthenes]] and [[Ptolemy]]—observing from [[Alexandria]]—did, calling it ''Kanōbos''.<ref name=ridpathCr>{{cite web| url=http://www.ianridpath.com/startales/carina.htm | title=Carina |last1=Ridpath|first1=Ian|publisher=self-published |work=Star Tales | access-date= 10 December 2015}}</ref> An [[Egypt]]ian priestly poet in the time of [[Thutmose III]] mentions the star as ''Karbana,'' "the star which pours his light in a glance of fire, when he disperses the morning dew."<ref name="hinkley63" /> Under the [[Ptolemies]], the star was known as ''Ptolemaion'' ([[Ancient Greek|Greek]]: Πτολεμαῖον) and its [[acronychal rising]] marked the date of the Ptolemaia festival, which was held every four years, from 262 to 145 BC.<ref>[[Martianus Capella]] 7.838, {{cite journal | last1 = Hazzard | last2 = Fitzgerald | year = 1991 | title = The Regulation of the Ptolemeia | journal = Journal of the Royal Astronomical Society of Canada | volume = 85 | pages = 6–23 |bibcode = 1991JRASC..85....6H }}; Hazzard. 2000. ''Imagination of a Monarchy: Studies in Ptolemaic Propaganda'', 34–36.</ref>
[[File:Statue of Averroes in Córdoba, Spain.jpg|thumb|upright|[[Averroes]], who used his 1153 observation of Canopus in [[Marrakesh]] while the star was invisible in his native Spain as an argument that the [[Spherical Earth|earth is round]].<ref name=ibn_rushd/>]]
===India===
In Indian [[Vedas|Vedic literature]], Canopus is associated with the sage [[Agastya]], one of the ancient [[siddhar]]s and [[rishi]]s (the others are associated with the stars of the [[Big Dipper]]).<ref name="Frawley 1993">{{cite book|last=Frawley|first=David|title=Gods, Sages and Kings: Vedic Secrets of Ancient Civilization|publisher=Motilal Banarsidass |location=New Delhi, India|date=1993}}</ref> To Agastya, the star is said to be the 'cleanser of waters', and its rising coincides with the calming of the waters of the [[Indian Ocean]]. It is thus considered the son of [[Pulastya]], son of [[Brahma]]. Canopus is described by [[Pliny the Elder]] and [[Gaius Julius Solinus]] as the largest, brightest and only source of [[starlight]] for navigators near [[Tamraparni]] island (ancient Sri Lanka) during many nights.<ref>{{cite book |last1=Pridham |first1=Charles |title=An Historical, Political, and Statistical Account of Ceylon and Its Dependencies |date=1849 |publisher=T. and W. Boone |page=7 |url=https://books.google.com/books?id=O4aqHOMSJdYC&pg=PR19-IA5|language=en}}</ref><ref name="Frawley 1993"/><ref>{{cite book |last1=Elder |first1=Pliny the |title=Delphi Complete Works of Pliny the Elder (Illustrated) |date=2015 |publisher=Delphi Classics |url=https://books.google.com/books?id=OrJ0CgAAQBAJ&pg=PA343|language=en}}</ref>
===China===
Canopus was described as Shou Xing, the Star of Longevity, in the ''Shiji'' ([[Records of the Grand Historian]]) completed in 94 BC by Chinese historian [[Sima Qian]].<ref name=fong83>{{cite journal | title=The Iconography of the Popular Gods of Happiness, Emolument, and Longevity (Fu Lu Shou) | first=Mary H. |last=Fong | journal=Artibus Asiae | volume= 44 | issue= 2/3 | year=1983| pages= 159–199 | doi= 10.2307/3249596| jstor=3249596 }}</ref> Drawing on sources from the [[Warring States period]], he noted it to be the southern counterpart of [[Sirius]],<ref name="IDP"/> and wrote of a sanctuary dedicated to it established by Emperor [[Qin Shi Huang]] between 221 and 210 BC. During the [[Han dynasty]], the star was auspicious, its appearance in the southern sky heralding peace and absence war.<ref name=fong83/> From the imperial capital [[Chang'an]], the star made a low transit across the southern sky, indicating true south to observers, and was often obscured by clouds.<ref name=baumann19>{{cite journal | title=The White Old Man: Géluk-Mongolian Canopus Allegory and the Existence of God | first=Brian | last=Baumann | journal= Central Asiatic Journal | volume= 62 | issue= 1 | year=2019| pages= 35–68 | doi=10.13173/centasiaj.62.1.0035| s2cid=213083544 }}</ref> During this time it was also equated with [[Old Man of the South Pole]] (in {{zh|c=南极老人|p=Nanji Lǎorén}})<ref name=fong83/> Under this name, Canopus appears (albeit misplaced northwards) on the medieval Chinese manuscript the [[Dunhuang Star Chart]], although it cannot be seen from the Chinese capital of [[Chang'an]].<ref name="IDP">{{cite journal|bibcode=2009JAHH...12...39B|arxiv=0906.3034|title=The Dunhuang Sky: A Comprehensive Study of the Oldest Known Star Atlas|volume=12|issue=1|pages=39–59|last1=Bonnet-Bidaud|first1=Jean-Marc |last2=Praderie|first2=Françoise |last3=Whitfield|first3=Susan |author-link=Susan Whitfield |journal=The International Dunhuang Project: The Silk Road Online|year=2009}}</ref> The Chinese astronomer [[Yi Xing]] had journeyed south to chart Canopus and other far southern stars in 724 AD.<ref>{{cite book|last=Needham|first=Joseph|title=Science and Civilisation in China: Volume 3, Mathematics and the Sciences of the Heavens and the Earth|publisher=Cambridge University Press|location=Cambridge, United Kingdom|date=1959|pages=274|isbn=0521058015}}</ref> Its personification as the Old Man Star was popularised in the [[Tang Dynasty]], where it appeared often in poetry and memorials. Later still, during the [[Ming Dynasty]], the star was established as one of the [[Sanxing (deities)|Three Stars]] (Fu Lo Shou), appearing frequently in art and literature of the time.<ref name=fong83/> This symbolism spread into neighbouring cultures in Asia.<ref name=baumann19/>
In Japan, Canopus is known as ''Mera-boshi'' and ''Roujin-sei'' (the old man star),<ref>{{cite conference |url=http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |title=Stellar Iconology and Astronomical Folklore in Japan |author=Takao Ibaraki |book-title=International Planetarium Society (IPS) Conferences 1996 |publisher=International Planetarium Society |location=Osaka |date=14 July 1996 |access-date=25 February 2012 |url-status=dead |archive-url=https://web.archive.org/web/20120326195757/http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |archive-date=2012-03-26 }}</ref> and in Mongolia, it was personified as the White Old Man.<ref name=fong83/> Although the link was known in Tibet, with names such as ''Genpo karpo'' (''Rgan po dkar po'') or ''Genkar'' (''Rgan dkar'') "White Old Man", the symbolism was not popular. Instead, Canopus was more commonly named ''Karma Rishi སྐར་མ་རི་ཥི།'', derived from Indian mythology. Tibetans celebrated the star's heliacal rising with ritual bathing and associated it with morning dew.<ref name=baumann19/>
===Polynesia===
Bright stars were important to the ancient [[Polynesian culture|Polynesians]] for navigation between the many islands and atolls of the Pacific Ocean. Low on the horizon, they acted as stellar compasses to assist mariners in charting courses to particular destinations. Canopus served as the southern wingtip of a "Great Bird" constellation called ''Manu'', with Sirius as the body and [[Procyon]] the northern wingtip, which divided the Polynesian night sky into two hemispheres.<ref name="Holberg">{{cite book | last=Holberg | first=J.B. | title=Sirius: Brightest Diamond in the Night Sky | date=2007 | publisher=Praxis Publishing | location=Chichester, UK | isbn=978-0-387-48941-4 | pages=[https://archive.org/details/siriusbrightestd0000holb/page/25 25–26] | url=https://archive.org/details/siriusbrightestd0000holb/page/25 }}</ref> The [[Hawaiian people]] called Canopus ''Ke Alii-o-kona-i-ka-lewa'', "The chief of the southern expanse"; it was one of the stars used by [[Hawaiʻiloa]] and Ki when they traveled to the [[Southern Ocean]].{{sfn|Makemson|1941|p=198}} The [[Māori people]] of [[New Zealand|New Zealand/Aotearoa]] had several names for Canopus. ''[[Ariki]]'' ("High-born"), was known as a solitary star that appeared in the east, prompting people to weep and chant.{{sfn|Makemson|1941|p=201}} They also named it ''[[Atutahi]]'', ''Aotahi'' or ''Atuatahi'', "Stand Alone".<ref>p. 419, [https://books.google.com/books?id=p7dR2w1Wv2sC ''Mythology: Myths, Legends and Fantasies''], Janet Parker, Alice Mills, Julie Stanton, Durban, Struik Publishers, 2007.</ref> Its solitary nature indicates it is a ''[[Tapu (Polynesian culture)|tapu]]'' star, as ''tapu'' people are often solitary. Its appearance at the beginning of the ''Maruaroa'' season foretells the coming winter; light rays to the south indicate a cold wet winter, and to the north foretell a mild winter. Food was offered to the star on its appearance.<ref name="Best22">{{cite book|last=Best|first=Elsdon|title=Astronomical Knowledge of the Maori: Genuine and Empirical|publisher=Dominion Museum|location=Wellington, New Zealand|date=1922|pages=34–35|url=http://nzetc.victoria.ac.nz/tm/scholarly/tei-BesAstro-t1-body-d1-d6-d4.html}}</ref> This name has several mythologies attached to it. One story tells of how Atutahi was left outside the basket representing the [[Milky Way]] when [[Tāne]] wove it. Another related myth about the star says that Atutahi was the first-born child of [[Rangi and Papa|Rangi]], who refused to enter the Milky Way and so turned it sideways and rose before it. The same name is used for other stars and constellations throughout Polynesia.{{sfn|Makemson|1941|pp=200–202}} ''Kapae-poto'', "Short horizon", referred to it rarely setting as seen in New Zealand;{{sfn|Makemson|1941|p=217}} ''Kauanga'' ("Solitary") was the name for Canopus only when it was the last star visible before sunrise.{{sfn|Makemson|1941|p=218}} The people of the [[Society Islands]] had two names for Canopus, as did the [[Tuamotu]] people. The Society Islanders called Canopus ''Taurua-e-tupu-tai-nanu'', "Festivity-whence-comes-the-flux-of-the-sea", and ''Taurua-nui-o-te-hiti-apatoa'' "Great-festivity-of-the-border-of-the-south",{{sfn|Makemson|1941|p=259}} and the Tuamotu people called the star ''Te Tau-rari'' and ''Marere-te-tavahi'', the latter said to be the true name for the former, "He-who-stands-alone".{{sfn|Makemson|1941|p=229}}
===Africa===
In the [[Guanches|Guanche]] mythology of the island of [[Tenerife]] (Spain), the star Canopus was linked with the goddess [[Chaxiraxi]].<ref name="Rumeu">{{cite book|author=Antonio Rumeu de Armas|title=La conquista de Tenerife, 1494–1496|url=https://books.google.com/books?id=Ck4BAAAAMAAJ|year=1975|publisher=Aula de Cultura de Tenerife|isbn=9788450071078}}</ref>
The [[Tswana people]] of [[Botswana]] knew Canopus as ''Naka''. Appearing late in winter skies, it heralded increasing winds and a time when trees lose their leaves. Stock owners knew it was time to put their sheep with rams.<ref>{{cite journal|last=Clegg|first=Andrew|date=1986|title=Some Aspects of Tswana Cosmology|journal=Botswana Notes and Records|volume=18|pages=33–37|jstor=40979758 }}</ref> In southern Africa, the Sotho, Tswana and Venda people called Canopus ''Naka'' or ''Nanga'', “the Horn Star”, while the Zulu and Swazi called it ''inKhwenkwezi'' "Brilliant star". It appears in the predawn sky in the third week of May. According to the Venda, the first person to see Canopus would blow a ''phalaphala'' horn from the top of a hill, getting a cow for a reward. The Sotho chiefs also awarded a cow, and ordered their medicine men to roll bone dice and read the fortune for the coming year.<ref name=snedegar95>{{cite journal |last1=Snedegar |first1=K.V. |title=Stars and seasons in Southern Africa |journal=Vistas in Astronomy |date=1995 |volume=39 |issue=4 |pages=529–38 |doi=10.1016/0083-6656(95)00008-9|bibcode=1995VA.....39..529S }}</ref> To the [[ǀXam language|ǀXam]]-speaking [[Bushmen]] of South Africa, Canopus and Sirius signalled the appearance of termites and flying ants. They also believed that stars had the power to cause death and misfortune, and they would pray to [[Sirius]] and Canopus in particular to impart good fortune or skill.<ref>{{cite journal| title="The Sky's Things", <nowiki>|</nowiki>xam Bushman 'Astrological Mythology' as recorded in the Bleek and Lloyd Manuscripts |last1=Hollman|first1=J. C.|journal=African Sky|volume= 11|page=8 |bibcode=2007AfrSk..11....8H|year = 2007 }}</ref> The [[ǃKung people]] of the [[Kalahari Desert]] in Botswana held Canopus and Capella to be the horns of ''tshxum'' (the Pleiades), the appearance of all three marking the end of the dry season and start of the rainy season.<ref>{{cite journal |last1=Marshall |first1=Lorna |title=Two Ju/ wa constellations |journal=Botswana Notes & Records |date=1975 |volume=7 |issue=1 |pages=153–159 | issn=0525-5090 |url=https://journals.co.za/docserver/fulltext/botnotes/7/1/548.pdf?expires=1590793041&id=id&accname=guest&checksum=3204085F9555AD9D083799E1F38E3AED}}</ref>
===Americas===
The [[Navajo]] observed the star and named it ''Maʼii Bizòʼ'', the “Coyote Star”. According to legend, Maʼii (Coyote) took part in the naming and placing of the star constellations during
the creation of the universe. He placed Canopus directly south, naming it after himself.<ref name="Maryboy">Maryboy, Nancy D. (2004). ''A Guide to Navajo Astronomy.'' Indigenous Education Institute : Bluff, Utah.</ref>
The [[Kalapalo]] people of [[Mato Grosso]] state in Brazil saw Canopus and [[Procyon]] as ''Kofongo'' "Duck", with [[Castor (star)|Castor]] and [[Pollux (star)|Pollux]] representing his hands. The asterism's appearance signified the coming of the rainy season and increase in [[manioc]], a food staple fed to guests at feasts.<ref name="basso87">{{cite book|last=Basso|first=Ellen B. |title=In Favor of Deceit: A Study of Tricksters in an Amazonian Society|publisher=University of Arizona Press|location=Tucson, Arizona|date=1987|page=[https://archive.org/details/infavorofdeceits0000bass/page/360 360]|isbn=0816510229|url=https://archive.org/details/infavorofdeceits0000bass|url-access=registration}}</ref>
===Australia===
Canopus is identified as the moiety ancestor ''Waa'' "Crow" to some [[Koori]] people in southeastern Australia.<ref>{{cite book|last=Mudrooroo|title=Aboriginal mythology: an A-Z spanning the history of aboriginal mythology from the earliest legends to the present day|publisher=HarperCollins|location=London|date=1994|page=27|isbn=1-85538-306-3}}</ref> The Boorong people of northwestern Victoria recalled that ''War'' (Canopus) was the brother of ''Warepil'' (Sirius), and that he brought fire from the heavens and introduced it to humanity. His wife was ''Collowgullouric War'' ([[Eta Carinae]]).<ref name=hamacher10>{{cite journal|last1=Hamacher|first1=Duane W. |last2=Frew|first2=David J. |date=2010|title= An Aboriginal Australian Record of the Great Eruption of Eta Carinae|journal=Journal of Astronomical History & Heritage |volume=13|issue=3|pages= 220–34|bibcode=2010JAHH...13..220H|arxiv = 1010.4610 }}</ref> The Pirt-Kopan-noot people of western Victoria tell of ''Waa'' "Crow" falling in love with a queen, ''Gneeanggar'' "Wedge-tailed Eagle" (Sirius) and her six attendants (the Pleiades). His advances spurned, he hears that the women are foraging for grubs and so transforms himself into a grub. When the women dig him out, he changes into a giant and carries her off.<ref>Mudroodoo, p. 55.</ref>
The Kulin people know Canopus as ''Lo-an-tuka''.<ref name=hamacher10/> Objects in the sky are also associated with states of being for some tribes; the Wailwun of northern New South Wales know Canopus as ''Wumba'' "deaf", alongside Mars as ''Gumba'' "fat" and Venus as ''Ngindigindoer'' "you are laughing".<ref name="noctuary">{{cite book|last=Johnson|first=Diane|title=Night skies of aboriginal Australia: a noctuary|publisher=University of Sydney|location=Darlington, New South Wales|date=1998|page=[https://archive.org/details/nightskiesofabor0000john/page/84 84]|isbn=1-86451-356-X|url-access=registration|url=https://archive.org/details/nightskiesofabor0000john/page/84}}</ref> Tasmanian aboriginal lore holds that Canopus is ''Dromerdene'', the brother of ''Moinee''; the two fought and fell out of the sky, with ''Dromerdene'' falling into Louisa Bay in southwest Tasmania.<ref name="haynes2000">{{cite book|last=Haynes|first=Ros D.|title= Astronomy and the Dreaming: The Astronomy of the Aboriginal Australians. Astronomy Across Cultures: The History of Non-Western Astronomy|publisher=Kluwer Academic Publishers|date=2000|page=57|doi=10.1007/978-94-011-4179-6_3}}</ref>
===Legacy===
[[File:HMS Glory LOC ggbain.17135.jpg|thumb|right|[[Canopus-class battleship]] HMS Glory]]
Canopus appears on the [[flag of Brazil]], symbolising the state of [[Goiás]].<ref>{{cite web
|title=Astronomy of the Brazilian Flag
|url=https://flagspot.net/flags/br_astro.html
|publisher=FOTW Flags Of The World website
}}</ref>
Two U.S. Navy [[submarine tender]]s have been named after Canopus, the [[USS Canopus (AS-9)|first]] serving from 1922 to 1942 and the [[USS Canopus (AS-34)|second]] serving from 1965 to 1994.
The [[Royal Navy]] built nine [[Canopus-class ship of the line|Canopus-class ships of the line]] in the early 19th century, and six {{Sclass|Canopus|battleship|1}}s which entered services between 1899 and 1902.
There are at least two mountains named after the star: [[Mount Canopus]] in Antarctica; and Mount Canopus or Canopus Hill in [[Tasmania]], the location of the [[Canopus Hill Observatory|Canopus Hill astronomical observatory]].
{{clear}}
==See also==
*[[List of brightest stars]]
*[[List of most luminous stars]]
*[[Dune (novel)]]
==References==
{{Reflist|30em}}
===Bibliography===
* {{cite book | last = Makemson | first = Maud Worcester | date = 1941 | publisher = [[Yale University Press]] | title = The Morning Star Rises: an account of Polynesian astronomy | bibcode = 1941msra.book.....M }}
* {{cite book |title=The Brightest Stars: Discovering the Universe through the Sky's Most Brilliant Stars |last=Schaaf |first=Fred |year=2008 |publisher=John Wiley & Sons |location=Hoboken, NJ |isbn=978-0-471-70410-2 }}
30cd98e20631d240912f0a4c2c6c03e68c62bf1d
350
349
2022-09-04T15:29:34Z
SpaceMan
2
Canopus
wikitext
text/x-wiki
{{short description|Bright giant star in the constellation of Carina}}
{{Other uses}}
{{Starbox begin
| name=Canopus
}}
{{Starbox image
| image=[[File:Canopus.jpg|255px]]
| caption=An image of Canopus by [[Expedition 6]]
}}
{{Starbox observe
| epoch=J2000
| constell=[[Carina (constellation)|Carina]]
| pronounce={{IPAc-en|k|ə|ˈ|n|oʊ|p|ə|s}}<ref>{{OED|Canopus}}</ref>
| ra={{RA|06|23|57.10988}}<ref name="van Leeuwen2007">{{cite journal | title=Validation of the new Hipparcos reduction | last1=van Leeuwen | first1=F. | journal=Astronomy and Astrophysics | volume=474 | issue=2 | pages=653–664 | date=2007 | arxiv=0708.1752 | bibcode=2007A&A...474..653V | doi=10.1051/0004-6361:20078357 | s2cid=18759600 }} [http://webviz.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b48255b3&-out.add=.&-source=I/311/hip2&recno=30362 Vizier catalog entry ]</ref>
| dec={{DEC|-52|41|44.3810}}<ref name="van Leeuwen2007"/>
| appmag_v=−0.74<ref name="Ducati 2002">{{cite journal | title=Catalogue of Stellar Photometry in Johnson's 11-color system | last1=Ducati | first1=J. R. | journal=CDS/ADC Collection of Electronic Catalogues | volume=2237 | pages=0 | date=2002 | bibcode=2002yCat.2237....0D }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b360304a&-out.add=.&-source=II/237/colors&recno=1155 Vizier catalog entry ]</ref>
}}
{{Starbox character
| type=
| class=A9 II<ref name=perkins>{{cite journal|bibcode=1989ApJS...69..301G|title=The early F-type stars – Refined classification, confrontation with Stromgren photometry, and the effects of rotation|journal=Astrophysical Journal Supplement Series|volume=69|pages=301|last1=Gray|first1=R. O.|last2=Garrison|first2=R. F.|year=1989|doi=10.1086/191315}}</ref><ref>{{cite journal|bibcode=1993ASPC...45...59L|title=A Spectroscopic Study of High Galactic Latitude F Supergiant Stars|journal=Luminous High-Latitude Stars. The International Workshop on Luminous High-Latitude Stars|volume=45|pages=59|last1=Lopez-Cruz|first1=O.|last2=Garrison|first2=R. F.|year=1993}}</ref>
| b-v=+0.15<ref name="Ducati 2002"/>
| u-b=+0.10<ref name="Ducati 2002"/>
| variable=
}}
{{Starbox astrometry
| radial_v={{val|20.3|0.5}}<ref name="Gontcharov 2007">{{cite journal | title=Pullkovo Compilation of Radial Velocities for 39495 Hipparcos stars in a common system | last1=Gontcharov | first1=G. A. | journal=Astronomy Letters | volume=32 | issue=1 | pages=759–771 | date=2007 | bibcode=2006AstL...32..759G | doi=10.1134/S1063773706110065|arxiv = 1606.08053 | s2cid=119231169 }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b5f60fbd&-out.add=.&-source=III/252/table8&recno=9232 Vizier catalog entry ]</ref>
| prop_mo_ra=19.93<ref name="van Leeuwen2007"/>
| prop_mo_dec=23.24<ref name="van Leeuwen2007"/>
| parallax=10.55
| p_error=0.56
| parallax_footnote=<ref name="van Leeuwen2007"/>
| absmag_v=–5.71<ref name=smiljanic2006/>
|arxiv = 1606.08053 }}
{{Starbox detail
| metal_fe=–0.07<ref name=smiljanic2006/>
| mass={{Val|8.0|0.3}}<ref name=vlti>{{cite journal|bibcode=2013MNRAS.434..437C|arxiv=1306.3288|title=Fundamental parameters of 16 late-type stars derived from their angular diameter measured with VLTI/AMBER|journal=Monthly Notices of the Royal Astronomical Society|volume=434|issue=1|pages=437–450|last1=Cruzalèbes|first1=P.|last2=Jorissen|first2=A.|last3=Rabbia|first3=Y.|last4=Sacuto|first4=S.|last5=Chiavassa|first5=A.|last6=Pasquato|first6=E.|last7=Plez|first7=B.|last8=Eriksson|first8=K.|last9=Spang|first9=A.|last10=Chesneau|first10=O.|year=2013|doi=10.1093/mnras/stt1037|s2cid=49573767}}</ref> (2013)<br/>{{val|10.1|0.1}}<ref name=Tetzlaff2011/> (2011)
| radius={{Val|71|4}}<ref name=vlti/> (2013)<br>{{val|73.3|5.2}}<ref name=DomicianoDeSouza>{{cite journal|doi=10.1051/0004-6361/202140478|title=Refined fundamental parameters of Canopus from combined near-IR interferometry and spectral energy distribution|year=2021|last1=Domiciano De Souza|first1=A.|last2=Zorec|first2=J.|last3=Millour|first3=F.|last4=Le Bouquin|first4=J.-B.|last5=Spang|first5=A.|last6=Vakili|first6=F.|journal=Astronomy & Astrophysics|volume=654|pages=A19|arxiv=2109.07153|bibcode=2021A&A...654A..19D|s2cid=237513623}}</ref> (2021)
| gravity={{Val|1.70|0.05}}<ref name=DomicianoDeSouza/>
| rotational_velocity=9<ref name=ayres2018/>
| rotation={{val|298|u=days|p=≥}}<ref name=Testa2004/>
| luminosity=10,700<ref name=vlti/>
| temperature=7,400<ref name=ayres2018>{{cite journal |bibcode=2018ApJ...854...95A |title=Cracking the Conundrum of F-supergiant Coronae |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |year=2018 |volume=854 |issue=2 |page=95 |doi=10.3847/1538-4357/aaa6d7 |arxiv=1802.02552 |s2cid=119101035 }}</ref>
| age_myr = {{val|25.1|2.5}}<ref name=Tetzlaff2011>{{cite journal | title=A catalogue of young runaway Hipparcos stars within 3 kpc from the Sun | last1=Tetzlaff | first1=N. | last2=Neuhäuser | first2=R. | last3=Hohle | first3=M. M. | journal=Monthly Notices of the Royal Astronomical Society | volume=410 | issue=1 | pages=190–200 | date=January 2011 | doi=10.1111/j.1365-2966.2010.17434.x | arxiv=1007.4883 | bibcode=2011MNRAS.410..190T | s2cid=118629873 }}</ref>
}}
{{Starbox catalog
| names={{odlist | name=Suhayl | name2=Suhel | name3=Suhail | B=α Carinae | CPD=−52°1941 | FK5=245 | HD=45348 | HIP=30438 | HR=2326 | SAO=234480| GC=8302 }}<ref name=SIMBAD>{{cite simbad | title=alf Car | access-date=2019-03-09 }}</ref>
}}
{{Starbox reference
| Simbad=canopus
}}
{{Starbox end}}
'''Canopus''' is the brightest star in the southern [[constellation]] of [[Carina (constellation)|Carina]] and the [[list of brightest stars|second-brightest star]] in the [[night sky]]. It is also [[Bayer designation|designated]] '''α Carinae''', which is [[Latinisation of names|Latinised]] to '''Alpha Carinae'''. With a [[visual apparent magnitude]] of −0.74, it is outshone only by [[Sirius]]. Located around {{val|310|ul=light-years}} from the [[Sun]], Canopus is a [[bright giant]] of [[spectral type A9]], so it is essentially white when seen with the naked eye. It has a luminosity over 10,000 times the [[luminosity of the Sun]], is eight times as [[mass of the Sun|massive]], and has expanded to 71 times the [[Sun's radius]]. Its enlarged [[photosphere]] has an [[effective temperature]] of around {{val|7,400|fmt=commas|u=K}}. Canopus is undergoing [[stellar core|core]] [[helium fusion|helium burning]] and is currently in the so-called [[blue loop]] phase of its [[stellar evolution|evolution]], having already passed through the [[red-giant branch]] after exhausting the hydrogen in its core. Canopus is a [[X-ray astronomy|source of X-rays]], which are likely being emitted from its [[stellar corona|corona]].
The prominent appearance of Canopus means it has been the subject of mythological lore among many ancient peoples. Its proper name is generally considered to originate from the [[Greek mythology|mythological]] [[Canopus (mythology)|Canopus]], who was a navigator for [[Menelaus]], king of [[Sparta]]. The [[acronychal rising]] marked the date of the Ptolemaia festival in Egypt. In ancient India, it was named [[Agastya]] after the revered [[Vedas|Vedic]] sage. For Chinese astronomers, it was known as the [[Old Man of the South Pole]].
==Nomenclature==
The name ''Canopus'' is a Latinisation of the [[Ancient Greek]] name Κάνωβος/Kanôbos, recorded in Claudius Ptolemy's ''[[Almagest]]'' (c.150 AD). Eratosthenes used the same spelling.<ref name="ridpathCr"/> Hipparchos wrote it as Κάνωπος. [[John Flamsteed]] wrote Canobus,<ref>{{cite book|last=Flamsteed|first=John|title=Atlas coelestis|location=London, United Kingdom|date=1729|pages=Constellation Map of Southern Hemisphere|url=http://lhldigital.lindahall.org/u?/astro_atlas,1191}}</ref> as did [[Edmond Halley]] in his 1679 ''Catalogus Stellarum Australium''.<ref name="Halley 1679">{{cite book|last=Halley|first=Edmond|title=Catalogus stellarum australium; sive, Supplementum catalogi Tychenici, exhibens longitudines et latitudines stellarum fixarum, quae, prope polum Antarcticum sitae, in horizonte Uraniburgico Tychoni inconspicuae fuere, accurato calculo ex distantiis supputatas, & ad annum 1677 completum correctas...Accedit appendicula de rebus quibusdam astronomicis|publisher=T. James|location=London|date=1679|pages=30|url=http://babel.hathitrust.org/cgi/pt?id=mdp.39015007000170;view=1up;seq=41;size=150}}</ref> The name has two possible derivations, both listed in [[Richard Hinckley Allen]]'s seminal ''[[Star Names: Their Lore and Meaning]]''.
* [[Argo Navis]] was the ship used by [[Jason]] and the Argonauts in the legend of the [[Trojan War]]. The brightest star in the constellation was given the name of a ship's pilot from another Greek legend: [[Canopus (mythology)|Canopus]], pilot of [[Menelaus]]' ship on his quest to retrieve [[Helen of Troy]] after she was taken by [[Paris (mythology)|Paris]].<ref name="hinkley63">{{cite book|first=Richard Hinckley|last=Allen|author-link=Richard Hinckley Allen|date=1963|orig-year=1899|title=Star Names: Their Lore and Meaning|pages=[https://archive.org/details/starnamestheirlo00alle/page/67 67–72]|edition=Revised|publisher=Dover Publications|location=New York|isbn=0-486-21079-0|url-access=registration|url=https://archive.org/details/starnamestheirlo00alle/page/67}}</ref>
* A ruined ancient Egyptian port named [[Canopus, Egypt|Canopus]] lies near the mouth of the [[Nile]], site of the [[Battle of the Nile]]. It is speculated that its name is derived from the Egyptian [[Coptic language|Coptic]] ''Kahi Nub'' ("Golden Earth"), which refers to how Canopus would have appeared near the horizon in [[ancient Egypt]], reddened by atmospheric extinction from that position.<ref name="hinkley63"/><ref name=lynn1905>{{cite journal |bibcode=1905Obs....28..289L |title=The brightest fixed star and its name |last1=Lynn |first1=W. T. |journal=The Observatory |year=1905 |volume=28 |page=289 }}</ref>
In 2016, the [[International Astronomical Union]] organized a [[IAU Working Group on Star Names|Working Group on Star Names]] (WGSN) to catalog and standardize proper names for stars.<ref name="WGSN">{{cite web | url=https://www.iau.org/science/scientific_bodies/working_groups/280/ | title=IAU Working Group on Star Names (WGSN) | website=iau.org | publisher=[[International Astronomical Union]] | access-date=22 May 2016}}</ref> The WGSN's first bulletin of July 2016 included a table of the first two batches of names approved by the WGSN, which included ''Canopus'' for this star.<ref name="WGSN1">{{cite web | url=https://www.iau.org/static/science/scientific_bodies/working_groups/280/WGSN_bulletin1.pdf | title=Bulletin of the IAU Working Group on Star Names, No. 1 | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06 }}</ref> Canopus is now included in the ''IAU Catalog of Star Names''.<ref name="IAU-CSN">{{cite web | url=https://www.iau.org/public/themes/naming_stars/ | title=IAU Catalog of Star Names | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06}}</ref>
Canopus traditionally marked the rudder of the ship [[Argo Navis]].<ref>{{cite journal | title = On Frederick de Houtman's Catalogue of Southern Stars, and the Origin of the Southern Constellations | last1= Knobel|first1=E. B. |journal = [[Monthly Notices of the Royal Astronomical Society]] | volume= 77| issue= 5 | pages=414–432 [422] | bibcode = 1917MNRAS..77..414K |date=1917 | doi=10.1093/mnras/77.5.414| doi-access=free }}</ref> German celestial cartographer [[Johann Bayer]] gave it—as the brightest star in the constellation—the [[Bayer designation|designation]] of ''α Argus'' ([[Latinisation of names|Latinised]] to ''Alpha Argus'') in 1603. In 1763, French astronomer [[Nicolas Louis de Lacaille]] divided the huge constellation into three smaller ones,<ref name=Glass2012>{{cite book | title=Nicolas-Louis De La Caille, Astronomer and Geodesist | first=Ian Stewart | last=Glass | date=November 17, 2012 | page=73 | isbn=9780191649608 | publisher=OUP Oxford | url=https://www.google.com/books/edition/Nicolas_Louis_De_La_Caille_Astronomer_an/eZjlHAIBeRAC?hl=en&gbpv=1&pg=PT73 }}</ref> and hence Canopus became ''α Carinae'' ([[Latinisation of names|Latinised]] to ''Alpha Carinae''). It is listed in the [[Bright Star Catalogue]] as HR 2326, the [[Henry Draper Catalogue]] as HD 45348, and the [[Hipparcos catalogue]] as HIP 30438.<ref name=SIMBAD/> Flamsteed did not number this southern star, but [[Benjamin Apthorp Gould]] gave it the number 7 (7 G. Carinae) in his ''Uranometria Argentina''.<ref name=Gould1878>{{cite journal | title=Uranometria Argentina: Brightness and position of every fixed star, down to the seventh magnitude, within one hundred degrees of the South Pole; with atlas | last=Gould | first=Benjamin Apthorp | journal=Resultados del Observatorio Nacional Argentino | volume=1 | page=140 | date=1878 | bibcode=1879RNAO....1....1G }}</ref>
An occasional name seen in English is ''Soheil'', or the feminine Soheila; in Turkish is ''Süheyl'', or the feminine Süheyla, from the Arabic name for several bright stars, سهيل ''suhayl'',<ref name="hinkley63"/> and Canopus was known as Suhel {{IPAc-en|'|s|uː|h|E|l}} in medieval times.<ref name=kunitzsch/> Alternative spellings include Suhail, Souhail, Suhilon, Suheyl, Sohayl, Suhayil, Shoel, Sohil, Soheil, Sahil, Suhayeel, Sohayil, Sihel, and Sihil.<ref name="hinkley63"/> An alternative name was ''Wazn'' "weight" or ''Haḍar'' "ground", possibly related to its low position near the horizon.<ref name="hinkley63"/> Hence comes its name in the ''[[Alfonsine tables]]'', Suhel ponderosus, a Latinization of ''Al Suhayl al Wazn''.<ref name="hinkley63"/> Its Greek name was revived during the [[Renaissance]].<ref name=kunitzsch>{{cite book |last1=Kunitzsch|first1=Paul |last2=Smart|first2=Tim |date = 2006|title = A Dictionary of Modern star Names: A Short Guide to 254 Star Names and Their Derivations |edition = 2nd rev. |publisher = Sky Publishing Corporation |location = Cambridge, Massachusetts |isbn = 978-1-931559-44-7 |page = 23}}</ref>
==Observation==
[[File:Carina constellation map.svg|thumb|left|The constellation [[Carina (constellation)|Carina]] with Canopus towards the right (west)]]
The Spanish Muslim astronomer [[Ibn Rushd]] went to [[Marrakesh]] (in Morocco) to observe the star in 1153, as it was invisible in his native [[Córdoba, Spain|Córdoba]], [[Al-Andalus]]. He used the different visibility in different latitudes to argue that the [[Spherical Earth|earth is round]], following [[Spherical Earth#Aristotle|Aristotle's argument]] which held that such an observation was only possible if the earth was a relatively small sphere.<ref name=ibn_rushd>{{cite encyclopedia|first1=Juan|last1=Vernet|author-link1=Juan Vernet|first2=Julio|last2=Samsó|author-link2=Julio Samsó |title=The development of Arabic science in Andalusia |page=264|editor=[[Roshdi Rashed]]|encyclopedia=Encyclopedia of the History of Arabic Science | date=1996|publisher=Routledge|isbn=978-0-415-12410-2|oclc=912501823}}</ref>
English explorer [[Robert Hues]] brought Canopus to the attention of European observers in his 1592 work ''Tractatus de Globis'', along with [[Achernar]] and [[Alpha Centauri]], noting:<blockquote>"Now, therefore, there are but three [[First-magnitude star|Stars of the first magnitude]] that I could perceive in all those parts which are never seene here in England. The first of these is that bright Star in the sterne of [[Argo Navis|Argo]] which they call Canobus. The second is in the end of [[Eridanus (constellation)|Eridanus]]. The third is in the right foote of the [[Centaurus|Centaure]]."<ref>Knobel, p. 416.</ref></blockquote>
[[File:Vela and Surrounding Constellations (ground-based image).jpg|right|thumb|Wide angle view showing Canopus and other prominent stars with the Milky Way|alt=A field of stars against the Milky Way background with the prominent stars and constellations labelled]]
In the [[Southern Hemisphere]], Canopus and [[Sirius]] are both visible high in the sky simultaneously, and reach a [[meridian (astronomy)|meridian]] just {{val|21|u=minutes}} apart. Brighter than [[first-magnitude star|first magnitude]], Canopus can be seen by naked eye in the early twilight. Mostly visible in mid to late summer in the Southern Hemisphere, Canopus [[Culmination|culminates]] at midnight on December 27,<ref name="motz" /> and at 9 PM on February 11.<ref name="Schaaf257">Schaaf, p. 257.</ref>
When seen from latitudes south of {{DEC|37|18}} S, Canopus is a [[circumpolar star]]. Since Canopus is so far south in the sky, it never rises in mid- to far-northern latitudes; in theory the northern limit of visibility is latitude {{DEC|37|18}} north. This is just south of [[Athens]], [[Richmond, Virginia]] (USA), and [[San Francisco]], and very close to [[Seville]] and [[Agrigento]]. It is almost exactly the latitude of [[Lick Observatory]] on [[Mount Hamilton (California)|Mt. Hamilton, California]], from which it is readily visible because of the effects of elevation and [[atmospheric refraction]], which add another degree to its apparent altitude. Under ideal conditions, it can be spotted as far north as latitude {{DEC|37|31}} from the Pacific coast.<ref>D. Gieringer, "Exploring the Tropic of Canopus", ''Astronomy'', December 1985, p.24.</ref> Another northernmost record of visibility came from [[Mount Nemrut]] in Turkey, latitude {{DEC|37|59}}.<ref>{{cite web |last1=Tezel |first1=Tunç |author-link=Tunç Tezel |url=http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |title=Zodiacal Light and Nemrut Heritage |work=The World At Night (TWAN) |access-date=17 March 2014 |date=8 Oct 2013 |archive-url=https://web.archive.org/web/20140317134955/http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |archive-date=17 March 2014 |url-status=dead }}</ref> It is more easily visible in places such as the Gulf Coast and Florida, and the island of [[Crete]] (Greece) where the best season for viewing it around 9 p.m. is during late January and early February.<ref name="motz">{{cite book|last1=Motz|first1=Lloyd|last2=Nathanson|first2=Carol|title=The Constellations: An Enthusiast's Guide to the Night Sky|publisher=Aurum Press|location=London, United Kingdom|date=1991|pages=376–77|isbn=1-85410-088-2}}</ref>
Canopus has a B–V [[color index]] of +0.15—where 0 is a blue-white—indicating it is essentially white, although it has been described as yellow-white. Canopus' spectral type has been given as F0 and the incrementally warmer A9. It is less yellow than [[Altair]] or [[Procyon]], with indices measured as 0.22 and 0.42, respectively.<ref name=Hoffleit1991>{{cite book | title=Bright Star Catalogue | edition=5th Revised | last1=Hoffleit | first1=D. | last2=Warren Jr. | first2=W. H. | date=1991 | publisher=[[Centre de Données astronomiques de Strasbourg|CDS]] }}</ref> Some observers may have perceived Canopus as yellow-tinged because it is low in the sky and hence subject to atmospheric effects.<ref name="Schaaf112">Schaaf, pp. 112–13.</ref> [[Patrick Moore]] said that it never appeared anything but white to him.<ref name="moore2000">{{cite book | first1=Patrick | last1=Moore | title=Exploring the night sky with binoculars | edition=4th | publisher=Cambridge University Press | year=2000 | isbn=9780521793902 | page=[https://archive.org/details/exploringnightsk00moor/page/69 69] | url=https://archive.org/details/exploringnightsk00moor| url-access=registration }}</ref> The [[bolometric correction]] for Canopus is 0.00,<ref name=smiljanic2006/> indicating that the visual [[absolute magnitude]] and bolometric absolute magnitude are equal.
Canopus was previously proposed to be a member of the [[Scorpius–Centaurus association]], however it is not located near the subgroups of that association, and has not been included as a Sco-Cen member in kinematic studies that used [[Hipparcos]] astrometric data.<ref name="deZeeuw">{{cite journal|last1=de Zeeuw|first1=P.T. |last2=Hoogerwerf|first2=R. |last3=de Bruijne|first3=J.H.J |last4=Brown|first4=A.G.A |last5=Blaauw|first5=A. |date=1999|title=A HIPPARCOS Census of the Nearby OB Associations |journal=The Astronomical Journal |volume=117 |issue=1 |pages=354–399|bibcode=1999AJ....117..354D |doi=10.1086/300682|arxiv = astro-ph/9809227 |s2cid=16098861 }}</ref> Canopus is not thought to be a member of any nearby young stellar groups.<ref name=mamajek>{{cite journal | url=https://figshare.com/articles/Canopus_B_A_Candidate_Common_Proper_Motion_Companion_to_the_Second_Brightest_Star/1132696 | title=Canopus B: A Candidate Common Proper Motion Companion to the Second Brightest Star | last=Mamajek | first=Eric | year=2014 | publisher=Figshare | doi=10.6084/m9.figshare.1132696.v3 | access-date=2020-09-10 }}</ref> In 2014, astronomer Eric Mamajek reported that an extremely magnetically active M dwarf (having strong coronal X-ray emission), 1.16 degrees south of Canopus, appears to share a [[common proper motion]] with Canopus. The projected separation of the M dwarf 2MASS J06234738-5351131 ("Canopus B") is approximately 1.9 parsecs. However, despite this large separation, it is still within the estimated tidal radius (2.9 parsecs) for the massive star Canopus.<ref name="mamajek"/>
No star closer than Canopus is more luminous than it, and it has been the brightest star in Earth's night sky during three epochs over the past four million years. Other stars appear brighter only during relatively temporary periods, during which they are passing the Solar System much closer than Canopus. About 90,000 years ago, [[Sirius]] moved close enough that it became brighter than Canopus, and that will remain so for another 210,000 years. But in 480,000 years, as Sirius moves further away and appears fainter, Canopus will once again be the brightest, and will remain so for a period of about 510,000 years.<ref name="tomkin98">{{cite journal|last=Tomkin|first=Jocelyn|date=April 1998|title=Once and Future Celestial Kings|journal=Sky and Telescope|volume=95|issue=4|pages=59–63|bibcode=1998S&T....95d..59T}}</ref><!-- this all comes from same paper -->
===Role in navigation===
The southeastern wall of the [[Kaaba]] in [[Mecca]] is aligned with the rising point of Canopus, and is also named ''Janūb''.<ref>{{cite book|author=George Nicholas Atiyeh|title=The Book in the Islamic World: The Written Word and Communication in the Middle East|url=https://books.google.com/books?id=t4LEfpCW_kQC|date=1 January 1995|publisher=SUNY Press|isbn=978-0-7914-2473-5}}</ref> The [[Negev Bedouin|Bedouin]] people of the [[Negev]] and [[Sinai Peninsula|Sinai]] knew Canopus as ''Suhayl'', and used it and [[Polaris]] as the two principal stars for navigation at night. Because it disappears below the horizon in those regions, it became associated with a changeable nature, as opposed to always-visible Polaris, which was circumpolar and hence 'steadfast'.<ref>{{cite journal |last=Bailey |first=Clinton |date=1974 |title=Bedouin Star-Lore in Sinai and the Negev |journal=Bulletin of the School of Oriental and African Studies, University of London |volume=37 |issue=3 |pages=580–96 |type=abstract |doi=10.1017/S0041977X00127491 |jstor=613801|s2cid=131527348 }}</ref>
The south [[celestial pole]] can be approximately located using Canopus and another bright star, [[Achernar]], as the three make an [[equilateral triangle]]. Canopus sits on an imaginary line that extends {{DEC|36}} one way to Sirius and {{DEC|37}} to the south celestial pole.<ref>{{Cite book| last1 = Heifetz| first1 = Milton| last2 = Tirion| first2 = Wil| title = A Walk Through the Heavens: A Guide to Stars and Constellations and Their Legends | date = 2007| publisher = [[Cambridge University Press]]| location = Cambridge | page = 38 | isbn=978-1-139-46138-2}}</ref>
Canopus's brightness and location well off the [[ecliptic]] make it useful for space navigation. Many spacecraft carry a special camera known as a "Canopus [[star tracker|Star Tracker]]" plus a Sun sensor for [[Orientation (geometry)|attitude]] determination. [[Mariner 4]] used Canopus for [[Spin-stabilisation|second axis stabilisation]] (after locking on the Sun) in 1964, the first time a star had been used.<ref>{{cite book |last1=United States. National Aeronautics and Space Administration. Scientific and Technical Information Division |title=Astronautics and Aeronautics, 1964: Chronology on Science, Technology and Policy |date=1965 |publisher=Scientific and Technical Information Division, National Aeronautics and Space Administration |page=398 |url=https://books.google.com/books?id=ckkCAAAAIAAJ&pg=PA398}}</ref>
==Spectrum==
Canopus was little-studied by western scientists before the 20th century. It was given a spectral class of F in 1897, an early use of this extension to [[Secchi class]] I, applied to those stars where the hydrogen lines are relatively weak and the [[calcium K line]] relatively strong.<ref>{{cite journal |bibcode=1897ApJ.....6..349P |title=Spectra of bright southern stars |last1=Pickering |first1=E. C. |last2=Cannon |first2=A. J. |journal=The Astrophysical Journal |year=1897 |volume=6 |page=349 |doi=10.1086/140407 }}</ref> It was given as a standard star of F0 in the [[Henry Draper Catalogue]], with the spectral type F0 described as having hydrogen lines half the strength of an A0 star and the calcium K line three times as strong as Hδ.<ref name=hd>{{cite journal |bibcode=1918AnHar..92....1C |title=The Henry Draper catalogue : 4h, 5h and 6h |last1=Cannon |first1=Annie Jump |last2=Pickering |first2=Edward Charles |journal=Annals of Harvard College Observatory |year=1918 |volume=92 |page=1 }}</ref> American astronomer [[Jesse L. Greenstein|Jesse Greenstein]] was interested in stellar spectra and used the newly built [[Otto Struve Telescope]] at [[McDonald Observatory]] to analyze the star's spectrum in detail.<ref>{{cite book |last1=Trimble |first1=Virginia | first2= Thomas R. |last2=Williams | first3= Katherine | last3=Bracher| first4= Richard | last4=Jarrell| first5=Jordan D.| last5= Marché| first6=F. Jamil | last6=Ragep |title=Biographical Encyclopedia of Astronomers |date=2007 |publisher=Springer Science & Business Media |location=New York, New York |isbn=978-0-387-30400-7 |page=438 |url=https://books.google.com/books?id=t-BF1CHkc50C&pg=PA438}}</ref> In a 1942 paper, he reported that the spectrum is dominated by strong broad hydrogen lines. There are also [[absorption line]]s of carbon, nitrogen, oxygen, sulphur, iron, and many ionised metals.<ref name=greenstein1942>{{cite journal |bibcode=1942ApJ....95..161G |title=The Spectrum of α Carinae |last1=Greenstein |first1=Jesse L. |journal=The Astrophysical Journal |year=1942 |volume=95 |page=161 |doi=10.1086/144382 }}</ref> It was studied in the [[ultraviolet]] by an early astronomical satellite, [[Gemini XI]] in 1966. The UV spectra were considered to be consistent with an F0 [[Supergiant star|supergiant]] having a temperature of {{val|6,900|fmt=commas|u=K}}, the accepted parameters for Canopus at the time.<ref name=kondo1970>{{cite journal |bibcode=1970ApJ...159..927K |title=Ultraviolet Spectrophotometry of Canopus from Gemini XI |last1=Kondo |first1=Y. |last2=Henize |first2=K. G. |last3=Kotila |first3=C. L. |journal=The Astrophysical Journal |year=1970 |volume=159 |page=927 |doi=10.1086/150370 }}</ref> New Zealand-based astronomers [[John Hearnshaw]] and Krishna Desikachary examined the spectrum in greater detail, publishing their results in 1982.<ref>{{cite journal |title=The spectrum of Canopus | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 198 | year= 1982 | issue= 2 | pages= 311–320 | doi= 10.1093/mnras/198.2.311 | bibcode=1982MNRAS.198..311H| doi-access= free }}</ref><ref>{{cite journal |title=The spectrum of Canopus II - Analysis and composition | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 201 | year= 1982 | issue= 3 | pages= 707–721 | doi= 10.1093/mnras/201.3.707 | bibcode=1982MNRAS.201..707D| doi-access= free }}</ref>
When [[luminosity class]]es were added to the MK spectral classification scheme, Canopus was assigned class Iab indicating an intermediate luminosity supergiant. This was based on the relative strengths of certain spectral lines understood to be sensitive to the luminosity of a star.<ref name=devaucoleurs>{{cite journal|title=Spectral types and luminosities of B, A and F southern stars|author=de Vaucouleurs, A.|journal=Monthly Notices of the Royal Astronomical Society|volume=117|page=449|date=1957|issue=4|bibcode=1957MNRAS.117..449D|doi=10.1093/mnras/117.4.449|doi-access=free}}</ref> In the [[Bright Star Catalogue]] 5th edition it is given the spectral class F0II, the luminosity class indicating a [[bright giant]].<ref name=bsc>{{cite book |bibcode=1991bsc..book.....H |year=1991 |title=The Bright star catalogue |last1=Hoffleit |first1=Dorrit |last2=Jaschek |first2=Carlos }}</ref> [[Balmer line]] profiles and oxygen line strengths indicate the size and luminosity of Canopus.<ref name=kovtyukh2012>{{cite journal |bibcode=2012MNRAS.423.3268K |title=Accurate luminosities from the oxygen λ7771-4 Å triplet and the fundamental parameters of F-G supergiants |last1=Kovtyukh |first1=V. V. |last2=Gorlova |first2=N. I. |last3=Belik |first3=S. I. |journal=Monthly Notices of the Royal Astronomical Society |year=2012 |volume=423 |issue=4 |page=3268 |doi=10.1111/j.1365-2966.2012.21117.x |arxiv=1204.4115 |s2cid=118683158 }}</ref>
When the effects of stellar rotation speed on spectral lines are accounted for, the MK spectral class of Canopus is adjusted to A9II.<ref name=perkins/> Its spectrum consists mostly of absorption lines on a visible [[continuous spectrum|continuum]], but some emission has been detected. For example, the [[calcium K line]] have weak emission wings on each side of the strong central absorption line, first observed in 1966. The emission line profiles are usually correlated with the luminosity of the star as described by the [[Wilson-Bappu effect]], but in the case of Canopus they indicate a luminosity much lower than that calculated by other methods.<ref name=warner1966>{{cite journal|title=CA II emission in the spectrum of Canopus|journal=The Observatory |volume=86 |pages=82|date=April 1966|last=Warner |first=B. |bibcode=1966Obs....86...82W }}</ref> More detailed observations have shown that the emission line profiles are variable and may be due to [[plage (astronomy)|plage]] areas on the surface of the star. Emission can also be found in other lines such as the h and k lines of ionised magnesium.<ref name=bappu1984>{{cite journal |bibcode=1984BASI...12..196B |title=CA II K emission in Canopus |last1=Bappu |first1=M. K. V. |last2=Mekkaden |first2=M. V. |last3=Rao |first3=N. K. |journal=Bulletin of the Astronomical Society of India |year=1984 |volume=12 |page=196 }}</ref>
==Distance==
Before the launch of the [[Hipparcos]] satellite telescope, distance estimates for Canopus varied widely, from 96 [[light-year]]s to 1200 light-years. The closer distance was derived from parallax measurements of around {{val|33|ul=mas}}.<ref name=vandekamp1943>{{cite journal |title=Note on the Parallax of Canopus|journal=Popular Astronomy |volume=51 |date=1943 |page=172 |last=van de Kamp |first=Peter|bibcode=1943PA.....51..172V }}</ref> The larger distance derives from the assumption of a very bright [[absolute magnitude]] for Canopus.<ref name=vanzyl>{{cite book|author=J.E. van Zyl|title=Unveiling the Universe: An Introduction to Astronomy|url=https://books.google.com/books?id=Cj7uBwAAQBAJ&pg=PA184|date=6 December 2012|publisher=Springer Science & Business Media|isbn=978-1-4471-1037-8|pages=184–}}</ref>
Hipparcos established Canopus as being {{val|310|u=light-years}} ({{val|95|ul=parsecs}}) from the [[Solar System]]; this is based on its 2007 [[parallax]] measurement of {{Val|10.43|0.53|ul=mas}}.<ref name="van Leeuwen2007"/> At 95 parsecs, the [[interstellar extinction]] for Canopus is low at 0.26 magnitudes.<ref name=DomicianoDeSouza/> Canopus is too bright to be included in the normal observation runs of the [[Gaia satellite]] and there is no published Gaia parallax for it.<ref name=dr2>{{cite DR2}}</ref>
At present the star is drifting further away from the Sun with a [[radial velocity]] of 20 km/s. Some 3.1 million years ago it made the closest approach to the Sun at a distance of about {{convert|52.87|pc|ly|0|adj=ri0|order=flip|abbr=on|lk=off}}. Canopus is orbiting the Milky Way with a heliocentric velocity of 24.5 km/s and a low [[orbital eccentricity|eccentricity]] of 0.065.<ref name=Anderson2012>{{citation | last1=Anderson | first1=E. | last2=Francis | first2=Ch. | title=XHIP: An extended hipparcos compilation | journal=Astronomy Letters | volume=38 | issue=5 | pages=331 | year=2012 | bibcode=2012AstL...38..331A | arxiv=1108.4971 | doi=10.1134/S1063773712050015 | s2cid=119257644 | postscript=. }}</ref>
==Physical characteristics==
[[File:Constellation_Carina.jpg|thumb|right|upright|Canopus is the brightest star in the constellation of Carina (top).]]
The [[absorption line]]s in the spectrum of Canopus shift slightly with a period of {{val|6.9|u=days}}. This was first detected in 1906 and the [[doppler effect|Doppler]] variations were interpreted as orbital motion.<ref name=curtis1907>{{cite journal |bibcode=1907PASP...19R.259C |title=The orbits of the spectroscopic binaries alpha Carinae, kappa Velorum, and alpha Pavonis |last1=Curtis |first1=H. D. |journal=Publications of the Astronomical Society of the Pacific |year=1907 |volume=19 |page=259 |doi=10.1086/121781 }}</ref> An orbit was even calculated, but no such companion exists and the small radial velocity changes are due to movements in the atmosphere of the star. The maximum observed [[radial velocities]] are only 0.7 to {{val|1.6|ul=km/s}}. Canopus also has a magnetic field that varies with the same period, detected by the [[Zeeman splitting]] of its spectral lines.<ref name=weiss1986>{{cite journal |bibcode=1986A&A...160..243W | title=The magnetic field of Canopus | last=Weiss | first=W. W. | journal= Astronomy and Astrophysics |volume= 160|pages= 243–250 | year=1986}}</ref> Canopus is bright at [[microwave]] wavelengths, one of the few F-class stars to be detected by radio.<ref name=gudel2002>{{cite journal |bibcode=2002ARA&A..40..217G |title=Stellar Radio Astronomy: Probing Stellar Atmospheres from Protostars to Giants |last1=Güdel |first1=Manuel |journal=Annual Review of Astronomy and Astrophysics |year=2002 |volume=40 |pages=217–261 |doi=10.1146/annurev.astro.40.060401.093806 |arxiv=astro-ph/0206436 |s2cid=53633983 }}</ref> The [[rotation period]] of the star is not accurately known, but may be over three hundred days.<ref name=Testa2004>{{cite journal | title=The Density of Coronal Plasma in Active Stellar Coronae | last1=Testa | first1=Paola | last2=Drake | first2=Jeremy J. | last3=Peres | first3=Giovanni | journal=The Astrophysical Journal | volume=617 | issue=1 | pages=508–530 | date=December 2004 | doi=10.1086/422355 | arxiv=astro-ph/0405019 | bibcode=2004ApJ...617..508T | s2cid=17532089 }}</ref> The [[projected rotational velocity]] has been measured at 9 km/s.<ref name=ayres2018/>
An early [[Interferometry|interferometric]] measurement of its [[angular diameter]] in 1968 gave a [[Limb darkening|limb-darkened]] value of {{val|6.86|ul=mas}}, close to the accepted modern value.<ref>{{cite journal |bibcode=1968ARA&A...6...13B |title=Measurement of Stellar Diameters |last1=Brown |first1=R. Hanbury |journal=Annual Review of Astronomy and Astrophysics |year=1968 |volume=6 |page=13 |doi=10.1146/annurev.aa.06.090168.000305 }}</ref> [[Very-long-baseline interferometry]] has been used to calculate Canopus' angular diameter at {{val|6.9|ul=mas}}. Combined with distance calculated from its Hipparcos parallax, this gives it a radius of 71 times [[Solar radius|that of the Sun]].<ref name=vlti/> If it were at the centre of the Solar System, it would extend 90% of the way to the orbit of [[Mercury (planet)|Mercury]].<ref name=Kalerstars>{{cite web|url=http://stars.astro.illinois.edu/sow/canopus.html|title=Canopus|last=Kaler|first=Jim|work=Stars|publisher=University of Illinois|access-date=8 July 2012|date=26 June 2009}}</ref> The radius and temperature relative to the Sun means that it is 10,700 times more luminous than the Sun, and its position in the [[H-R diagram]] relative to theoretical [[stellar evolution|evolutionary]] tracks means that it is {{Val|8.0|0.3}} times as massive as the Sun.<ref name=vlti/> Measurements of its shape find a 1.1° departure from spherical symmetry.<ref name=cruzalebes2015>{{cite journal |bibcode=2015MNRAS.446.3277C |title=Departure from centrosymmetry of red giants and supergiants measured with VLTI/AMBER |last1=Cruzalèbes |first1=P. |last2=Jorissen |first2=A. |last3=Chiavassa |first3=A. |last4=Paladini |first4=C. |last5=Rabbia |first5=Y. |last6=Spang |first6=A. |journal=Monthly Notices of the Royal Astronomical Society |year=2015 |volume=446 |issue=4 |page=3277 |doi=10.1093/mnras/stu2382 |doi-access=free }}</ref>
Canopus is a source of [[X-ray astronomy|X-rays]], which are probably produced by its corona, magnetically heated to several million [[Kelvin]]. The temperature has likely been stimulated by fast rotation combined with strong convection percolating through the star's outer layers.<ref name=ness>{{cite journal|bibcode=2004A&A...427..667N|title=On the sizes of stellar X-ray coronae|journal=Astronomy and Astrophysics|volume=427|issue=2|pages=667–683|last1=Ness|first1=J.-U.|last2=Güdel|first2=M.|last3=Schmitt|first3=J. H. M. M.|last4=Audard|first4=M.|last5=Telleschi|first5=A.|year=2004|doi=10.1051/0004-6361:20040504|arxiv = astro-ph/0407231 |s2cid=11468731}}</ref> The soft X-ray sub-coronal X-ray emission is much weaker than the hard X-ray coronal emission. The same behaviour has been measured in other F-class supergiants such as [[α Persei]] and is now believed to be a normal property of such stars.<ref name=ayres2018/>
== Evolution ==
The spectrum of Canopus indicates that it has exhausted its core hydrogen and [[stellar evolution|evolved]] away from the [[main sequence]], where it spent some 30 million years of its existence as a blue-white star <!-- source suggests B2V but may be too exact --> of around 10 solar masses.<ref>{{cite journal |last1=Peimbert |first1=M. |last2=Wallerstein | first2= G.| last3= Pilachowski | first3= C. A. |title=An upper limit for the deuterium abundance in Canopus |journal=Astronomy and Astrophysics |date=1981 |volume=104 |issue=1 |pages=72–74 | bibcode=1981A&A...104...72P}}</ref> The position of Canopus in the [[H–R diagram]] indicates that it is currently in the core-helium burning phase.<ref name=vlti/> It is an intermediate mass star that has left the [[red-giant branch]] before its core became [[degenerate matter|degenerate]] and is now in a [[blue loop]].<ref name=desouza>{{Cite journal | last1 = Domiciano De Souza | first1 = A. | last2 = Bendjoya | first2 = P. | last3 = Vakili | first3 = F. | last4 = Millour | first4 = F. | last5 = Petrov | first5 = R. G. | title = Diameter and photospheric structures of Canopus from AMBER/VLTI interferometry | doi = 10.1051/0004-6361:200810450 | journal = Astronomy and Astrophysics | volume = 489 | issue = 2 | pages = L5–L8 | year = 2008 |bibcode = 2008A&A...489L...5D | url = https://hal.archives-ouvertes.fr/hal-00316994/document | doi-access = free }}</ref> Models of stellar evolution in the blue loop phase show that the length of the blue loop is strongly affected by rotation and mixing effects inside the star. It is difficult to determine whether a star is currently evolving towards hotter temperature or returning to cooler temperatures, since the evolutionary tracks for stars with different masses overlap during the blue loops.<ref name=smiljanic2006>{{cite journal |bibcode=2006A&A...449..655S |title=CNO in evolved intermediate mass stars |last1=Smiljanic |first1=R. |last2=Barbuy |first2=B. |last3=De Medeiros |first3=J. R. |last4=Maeder |first4=A. |journal=Astronomy and Astrophysics |year=2006 |volume=449 |issue=2 |page=655 |doi=10.1051/0004-6361:20054377 |arxiv=astro-ph/0511329 |s2cid=3711409 }}</ref>
Canopus lies on the warm side of the [[instability strip]] and does not pulsate like [[Cepheid variables]] of a similar luminosity.<ref name=ayres2011>{{cite journal |doi=10.1088/0004-637X/738/2/120 |title=The Curious Case of the Alpha Persei Corona: A Dwarf in Supergiant's Clothing? |year=2011 |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |volume=738 |issue=2 |page=120 |bibcode=2011ApJ...738..120A |doi-access=free }}</ref> However its atmosphere does appear to be unstable, showing strong signs of convection.<ref name=smiljanic2006/>
Canopus may not be massive enough for its [[nuclear fusion|fusion]] chain to reach iron and trigger a core collapse and subsequent [[supernova]], instead eventually becoming a neon-oxygen [[white dwarf]].<ref name=Kalerstars/>
==Cultural significance ==
Canopus was known to the ancient Mesopotamians and given the name ''NUN-ki'' and represented the city of [[Eridu]] in the ''Three Stars Each'' [[Babylonian star catalogues]] and later [[MUL.APIN]] around 1100 BC.<ref>{{cite journal | last = Rogers | first = John H. | date = 1998 | title = Origins of the Ancient Constellations: I. The Mesopotamian Traditions | journal = Journal of the British Astronomical Association | volume = 108 | issue = 1 | pages = 9–28 | bibcode = 1998JBAA..108....9R}}</ref> Today, the star [[Sigma Sagittarii]] is known by the common name Nunki.<ref name=allen>{{citation | page=359 | first1=Richard Hinckley | last1=Allen | title=Star Names, their lore and meaning}}</ref>
Canopus was not visible to the mainland [[Ancient Greece|ancient Greeks]] and [[Roman Empire|Romans]]; it was, however, visible to the [[ancient Egypt]]ians.<ref name="Schaaf107">Schaaf, p. 107.</ref> Hence [[Aratus]] did not write of the star as it remained below the horizon, while [[Eratosthenes]] and [[Ptolemy]]—observing from [[Alexandria]]—did, calling it ''Kanōbos''.<ref name=ridpathCr>{{cite web| url=http://www.ianridpath.com/startales/carina.htm | title=Carina |last1=Ridpath|first1=Ian|publisher=self-published |work=Star Tales | access-date= 10 December 2015}}</ref> An [[Egypt]]ian priestly poet in the time of [[Thutmose III]] mentions the star as ''Karbana,'' "the star which pours his light in a glance of fire, when he disperses the morning dew."<ref name="hinkley63" /> Under the [[Ptolemies]], the star was known as ''Ptolemaion'' ([[Ancient Greek|Greek]]: Πτολεμαῖον) and its [[acronychal rising]] marked the date of the Ptolemaia festival, which was held every four years, from 262 to 145 BC.<ref>[[Martianus Capella]] 7.838, {{cite journal | last1 = Hazzard | last2 = Fitzgerald | year = 1991 | title = The Regulation of the Ptolemeia | journal = Journal of the Royal Astronomical Society of Canada | volume = 85 | pages = 6–23 |bibcode = 1991JRASC..85....6H }}; Hazzard. 2000. ''Imagination of a Monarchy: Studies in Ptolemaic Propaganda'', 34–36.</ref>
[[File:Statue of Averroes in Córdoba, Spain.jpg|thumb|upright|[[Averroes]], who used his 1153 observation of Canopus in [[Marrakesh]] while the star was invisible in his native Spain as an argument that the [[Spherical Earth|earth is round]].<ref name=ibn_rushd/>]]
===India===
In Indian [[Vedas|Vedic literature]], Canopus is associated with the sage [[Agastya]], one of the ancient [[siddhar]]s and [[rishi]]s (the others are associated with the stars of the [[Big Dipper]]).<ref name="Frawley 1993">{{cite book|last=Frawley|first=David|title=Gods, Sages and Kings: Vedic Secrets of Ancient Civilization|publisher=Motilal Banarsidass |location=New Delhi, India|date=1993}}</ref> To Agastya, the star is said to be the 'cleanser of waters', and its rising coincides with the calming of the waters of the [[Indian Ocean]]. It is thus considered the son of [[Pulastya]], son of [[Brahma]]. Canopus is described by [[Pliny the Elder]] and [[Gaius Julius Solinus]] as the largest, brightest and only source of [[starlight]] for navigators near [[Tamraparni]] island (ancient Sri Lanka) during many nights.<ref>{{cite book |last1=Pridham |first1=Charles |title=An Historical, Political, and Statistical Account of Ceylon and Its Dependencies |date=1849 |publisher=T. and W. Boone |page=7 |url=https://books.google.com/books?id=O4aqHOMSJdYC&pg=PR19-IA5|language=en}}</ref><ref name="Frawley 1993"/><ref>{{cite book |last1=Elder |first1=Pliny the |title=Delphi Complete Works of Pliny the Elder (Illustrated) |date=2015 |publisher=Delphi Classics |url=https://books.google.com/books?id=OrJ0CgAAQBAJ&pg=PA343|language=en}}</ref>
===China===
Canopus was described as Shou Xing, the Star of Longevity, in the ''Shiji'' ([[Records of the Grand Historian]]) completed in 94 BC by Chinese historian [[Sima Qian]].<ref name=fong83>{{cite journal | title=The Iconography of the Popular Gods of Happiness, Emolument, and Longevity (Fu Lu Shou) | first=Mary H. |last=Fong | journal=Artibus Asiae | volume= 44 | issue= 2/3 | year=1983| pages= 159–199 | doi= 10.2307/3249596| jstor=3249596 }}</ref> Drawing on sources from the [[Warring States period]], he noted it to be the southern counterpart of [[Sirius]],<ref name="IDP"/> and wrote of a sanctuary dedicated to it established by Emperor [[Qin Shi Huang]] between 221 and 210 BC. During the [[Han dynasty]], the star was auspicious, its appearance in the southern sky heralding peace and absence war.<ref name=fong83/> From the imperial capital [[Chang'an]], the star made a low transit across the southern sky, indicating true south to observers, and was often obscured by clouds.<ref name=baumann19>{{cite journal | title=The White Old Man: Géluk-Mongolian Canopus Allegory and the Existence of God | first=Brian | last=Baumann | journal= Central Asiatic Journal | volume= 62 | issue= 1 | year=2019| pages= 35–68 | doi=10.13173/centasiaj.62.1.0035| s2cid=213083544 }}</ref> During this time it was also equated with [[Old Man of the South Pole]] (in {{zh|c=南极老人|p=Nanji Lǎorén}})<ref name=fong83/> Under this name, Canopus appears (albeit misplaced northwards) on the medieval Chinese manuscript the [[Dunhuang Star Chart]], although it cannot be seen from the Chinese capital of [[Chang'an]].<ref name="IDP">{{cite journal|bibcode=2009JAHH...12...39B|arxiv=0906.3034|title=The Dunhuang Sky: A Comprehensive Study of the Oldest Known Star Atlas|volume=12|issue=1|pages=39–59|last1=Bonnet-Bidaud|first1=Jean-Marc |last2=Praderie|first2=Françoise |last3=Whitfield|first3=Susan |author-link=Susan Whitfield |journal=The International Dunhuang Project: The Silk Road Online|year=2009}}</ref> The Chinese astronomer [[Yi Xing]] had journeyed south to chart Canopus and other far southern stars in 724 AD.<ref>{{cite book|last=Needham|first=Joseph|title=Science and Civilisation in China: Volume 3, Mathematics and the Sciences of the Heavens and the Earth|publisher=Cambridge University Press|location=Cambridge, United Kingdom|date=1959|pages=274|isbn=0521058015}}</ref> Its personification as the Old Man Star was popularised in the [[Tang Dynasty]], where it appeared often in poetry and memorials. Later still, during the [[Ming Dynasty]], the star was established as one of the [[Sanxing (deities)|Three Stars]] (Fu Lo Shou), appearing frequently in art and literature of the time.<ref name=fong83/> This symbolism spread into neighbouring cultures in Asia.<ref name=baumann19/>
In Japan, Canopus is known as ''Mera-boshi'' and ''Roujin-sei'' (the old man star),<ref>{{cite conference |url=http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |title=Stellar Iconology and Astronomical Folklore in Japan |author=Takao Ibaraki |book-title=International Planetarium Society (IPS) Conferences 1996 |publisher=International Planetarium Society |location=Osaka |date=14 July 1996 |access-date=25 February 2012 |url-status=dead |archive-url=https://web.archive.org/web/20120326195757/http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |archive-date=2012-03-26 }}</ref> and in Mongolia, it was personified as the White Old Man.<ref name=fong83/> Although the link was known in Tibet, with names such as ''Genpo karpo'' (''Rgan po dkar po'') or ''Genkar'' (''Rgan dkar'') "White Old Man", the symbolism was not popular. Instead, Canopus was more commonly named ''Karma Rishi སྐར་མ་རི་ཥི།'', derived from Indian mythology. Tibetans celebrated the star's heliacal rising with ritual bathing and associated it with morning dew.<ref name=baumann19/>
===Polynesia===
Bright stars were important to the ancient [[Polynesian culture|Polynesians]] for navigation between the many islands and atolls of the Pacific Ocean. Low on the horizon, they acted as stellar compasses to assist mariners in charting courses to particular destinations. Canopus served as the southern wingtip of a "Great Bird" constellation called ''Manu'', with Sirius as the body and [[Procyon]] the northern wingtip, which divided the Polynesian night sky into two hemispheres.<ref name="Holberg">{{cite book | last=Holberg | first=J.B. | title=Sirius: Brightest Diamond in the Night Sky | date=2007 | publisher=Praxis Publishing | location=Chichester, UK | isbn=978-0-387-48941-4 | pages=[https://archive.org/details/siriusbrightestd0000holb/page/25 25–26] | url=https://archive.org/details/siriusbrightestd0000holb/page/25 }}</ref> The [[Hawaiian people]] called Canopus ''Ke Alii-o-kona-i-ka-lewa'', "The chief of the southern expanse"; it was one of the stars used by [[Hawaiʻiloa]] and Ki when they traveled to the [[Southern Ocean]].{{sfn|Makemson|1941|p=198}} The [[Māori people]] of [[New Zealand|New Zealand/Aotearoa]] had several names for Canopus. ''[[Ariki]]'' ("High-born"), was known as a solitary star that appeared in the east, prompting people to weep and chant.{{sfn|Makemson|1941|p=201}} They also named it ''[[Atutahi]]'', ''Aotahi'' or ''Atuatahi'', "Stand Alone".<ref>p. 419, [https://books.google.com/books?id=p7dR2w1Wv2sC ''Mythology: Myths, Legends and Fantasies''], Janet Parker, Alice Mills, Julie Stanton, Durban, Struik Publishers, 2007.</ref> Its solitary nature indicates it is a ''[[Tapu (Polynesian culture)|tapu]]'' star, as ''tapu'' people are often solitary. Its appearance at the beginning of the ''Maruaroa'' season foretells the coming winter; light rays to the south indicate a cold wet winter, and to the north foretell a mild winter. Food was offered to the star on its appearance.<ref name="Best22">{{cite book|last=Best|first=Elsdon|title=Astronomical Knowledge of the Maori: Genuine and Empirical|publisher=Dominion Museum|location=Wellington, New Zealand|date=1922|pages=34–35|url=http://nzetc.victoria.ac.nz/tm/scholarly/tei-BesAstro-t1-body-d1-d6-d4.html}}</ref> This name has several mythologies attached to it. One story tells of how Atutahi was left outside the basket representing the [[Milky Way]] when [[Tāne]] wove it. Another related myth about the star says that Atutahi was the first-born child of [[Rangi and Papa|Rangi]], who refused to enter the Milky Way and so turned it sideways and rose before it. The same name is used for other stars and constellations throughout Polynesia.{{sfn|Makemson|1941|pp=200–202}} ''Kapae-poto'', "Short horizon", referred to it rarely setting as seen in New Zealand;{{sfn|Makemson|1941|p=217}} ''Kauanga'' ("Solitary") was the name for Canopus only when it was the last star visible before sunrise.{{sfn|Makemson|1941|p=218}} The people of the [[Society Islands]] had two names for Canopus, as did the [[Tuamotu]] people. The Society Islanders called Canopus ''Taurua-e-tupu-tai-nanu'', "Festivity-whence-comes-the-flux-of-the-sea", and ''Taurua-nui-o-te-hiti-apatoa'' "Great-festivity-of-the-border-of-the-south",{{sfn|Makemson|1941|p=259}} and the Tuamotu people called the star ''Te Tau-rari'' and ''Marere-te-tavahi'', the latter said to be the true name for the former, "He-who-stands-alone".{{sfn|Makemson|1941|p=229}}
===Africa===
In the [[Guanches|Guanche]] mythology of the island of [[Tenerife]] (Spain), the star Canopus was linked with the goddess [[Chaxiraxi]].<ref name="Rumeu">{{cite book|author=Antonio Rumeu de Armas|title=La conquista de Tenerife, 1494–1496|url=https://books.google.com/books?id=Ck4BAAAAMAAJ|year=1975|publisher=Aula de Cultura de Tenerife|isbn=9788450071078}}</ref>
The [[Tswana people]] of [[Botswana]] knew Canopus as ''Naka''. Appearing late in winter skies, it heralded increasing winds and a time when trees lose their leaves. Stock owners knew it was time to put their sheep with rams.<ref>{{cite journal|last=Clegg|first=Andrew|date=1986|title=Some Aspects of Tswana Cosmology|journal=Botswana Notes and Records|volume=18|pages=33–37|jstor=40979758 }}</ref> In southern Africa, the Sotho, Tswana and Venda people called Canopus ''Naka'' or ''Nanga'', “the Horn Star”, while the Zulu and Swazi called it ''inKhwenkwezi'' "Brilliant star". It appears in the predawn sky in the third week of May. According to the Venda, the first person to see Canopus would blow a ''phalaphala'' horn from the top of a hill, getting a cow for a reward. The Sotho chiefs also awarded a cow, and ordered their medicine men to roll bone dice and read the fortune for the coming year.<ref name=snedegar95>{{cite journal |last1=Snedegar |first1=K.V. |title=Stars and seasons in Southern Africa |journal=Vistas in Astronomy |date=1995 |volume=39 |issue=4 |pages=529–38 |doi=10.1016/0083-6656(95)00008-9|bibcode=1995VA.....39..529S }}</ref> To the [[ǀXam language|ǀXam]]-speaking [[Bushmen]] of South Africa, Canopus and Sirius signalled the appearance of termites and flying ants. They also believed that stars had the power to cause death and misfortune, and they would pray to [[Sirius]] and Canopus in particular to impart good fortune or skill.<ref>{{cite journal| title="The Sky's Things", <nowiki>|</nowiki>xam Bushman 'Astrological Mythology' as recorded in the Bleek and Lloyd Manuscripts |last1=Hollman|first1=J. C.|journal=African Sky|volume= 11|page=8 |bibcode=2007AfrSk..11....8H|year = 2007 }}</ref> The [[ǃKung people]] of the [[Kalahari Desert]] in Botswana held Canopus and Capella to be the horns of ''tshxum'' (the Pleiades), the appearance of all three marking the end of the dry season and start of the rainy season.<ref>{{cite journal |last1=Marshall |first1=Lorna |title=Two Ju/ wa constellations |journal=Botswana Notes & Records |date=1975 |volume=7 |issue=1 |pages=153–159 | issn=0525-5090 |url=https://journals.co.za/docserver/fulltext/botnotes/7/1/548.pdf?expires=1590793041&id=id&accname=guest&checksum=3204085F9555AD9D083799E1F38E3AED}}</ref>
===Americas===
The [[Navajo]] observed the star and named it ''Maʼii Bizòʼ'', the “Coyote Star”. According to legend, Maʼii (Coyote) took part in the naming and placing of the star constellations during
the creation of the universe. He placed Canopus directly south, naming it after himself.<ref name="Maryboy">Maryboy, Nancy D. (2004). ''A Guide to Navajo Astronomy.'' Indigenous Education Institute : Bluff, Utah.</ref>
The [[Kalapalo]] people of [[Mato Grosso]] state in Brazil saw Canopus and [[Procyon]] as ''Kofongo'' "Duck", with [[Castor (star)|Castor]] and [[Pollux (star)|Pollux]] representing his hands. The asterism's appearance signified the coming of the rainy season and increase in [[manioc]], a food staple fed to guests at feasts.<ref name="basso87">{{cite book|last=Basso|first=Ellen B. |title=In Favor of Deceit: A Study of Tricksters in an Amazonian Society|publisher=University of Arizona Press|location=Tucson, Arizona|date=1987|page=[https://archive.org/details/infavorofdeceits0000bass/page/360 360]|isbn=0816510229|url=https://archive.org/details/infavorofdeceits0000bass|url-access=registration}}</ref>
===Australia===
Canopus is identified as the moiety ancestor ''Waa'' "Crow" to some [[Koori]] people in southeastern Australia.<ref>{{cite book|last=Mudrooroo|title=Aboriginal mythology: an A-Z spanning the history of aboriginal mythology from the earliest legends to the present day|publisher=HarperCollins|location=London|date=1994|page=27|isbn=1-85538-306-3}}</ref> The Boorong people of northwestern Victoria recalled that ''War'' (Canopus) was the brother of ''Warepil'' (Sirius), and that he brought fire from the heavens and introduced it to humanity. His wife was ''Collowgullouric War'' ([[Eta Carinae]]).<ref name=hamacher10>{{cite journal|last1=Hamacher|first1=Duane W. |last2=Frew|first2=David J. |date=2010|title= An Aboriginal Australian Record of the Great Eruption of Eta Carinae|journal=Journal of Astronomical History & Heritage |volume=13|issue=3|pages= 220–34|bibcode=2010JAHH...13..220H|arxiv = 1010.4610 }}</ref> The Pirt-Kopan-noot people of western Victoria tell of ''Waa'' "Crow" falling in love with a queen, ''Gneeanggar'' "Wedge-tailed Eagle" (Sirius) and her six attendants (the Pleiades). His advances spurned, he hears that the women are foraging for grubs and so transforms himself into a grub. When the women dig him out, he changes into a giant and carries her off.<ref>Mudroodoo, p. 55.</ref>
The Kulin people know Canopus as ''Lo-an-tuka''.<ref name=hamacher10/> Objects in the sky are also associated with states of being for some tribes; the Wailwun of northern New South Wales know Canopus as ''Wumba'' "deaf", alongside Mars as ''Gumba'' "fat" and Venus as ''Ngindigindoer'' "you are laughing".<ref name="noctuary">{{cite book|last=Johnson|first=Diane|title=Night skies of aboriginal Australia: a noctuary|publisher=University of Sydney|location=Darlington, New South Wales|date=1998|page=[https://archive.org/details/nightskiesofabor0000john/page/84 84]|isbn=1-86451-356-X|url-access=registration|url=https://archive.org/details/nightskiesofabor0000john/page/84}}</ref> Tasmanian aboriginal lore holds that Canopus is ''Dromerdene'', the brother of ''Moinee''; the two fought and fell out of the sky, with ''Dromerdene'' falling into Louisa Bay in southwest Tasmania.<ref name="haynes2000">{{cite book|last=Haynes|first=Ros D.|title= Astronomy and the Dreaming: The Astronomy of the Aboriginal Australians. Astronomy Across Cultures: The History of Non-Western Astronomy|publisher=Kluwer Academic Publishers|date=2000|page=57|doi=10.1007/978-94-011-4179-6_3}}</ref>
===Legacy===
[[File:HMS Glory LOC ggbain.17135.jpg|thumb|right|[[Canopus-class battleship]] HMS Glory]]
Canopus appears on the [[flag of Brazil]], symbolising the state of [[Goiás]].<ref>{{cite web
|title=Astronomy of the Brazilian Flag
|url=https://flagspot.net/flags/br_astro.html
|publisher=FOTW Flags Of The World website
}}</ref>
Two U.S. Navy [[submarine tender]]s have been named after Canopus, the [[USS Canopus (AS-9)|first]] serving from 1922 to 1942 and the [[USS Canopus (AS-34)|second]] serving from 1965 to 1994.
The [[Royal Navy]] built nine [[Canopus-class ship of the line|Canopus-class ships of the line]] in the early 19th century, and six {{Sclass|Canopus|battleship|1}}s which entered services between 1899 and 1902.
There are at least two mountains named after the star: [[Mount Canopus]] in Antarctica; and Mount Canopus or Canopus Hill in [[Tasmania]], the location of the [[Canopus Hill Observatory|Canopus Hill astronomical observatory]].
{{clear}}
c86b7d744cb72178d88d269c62077bd1a55baad5
Main Page
0
1
351
86
2022-09-25T12:56:57Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
Welcome to {{SITENAME}}!
AstroBase is an online encyclopaedia for astronomy and a wiki. Currently in development.
===Quick List===
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
===Astronomy Database Portal===
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
52ca8de1d94227ffff184c7666ee73bc5ec5288f
352
351
2022-09-26T17:50:31Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
Welcome to {{SITENAME}}!
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc .
{{SITENAME}} is a project to create a wiki dedicated to astronomy.
==Quick List==
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
==Astronomy Database Portal==
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
a9a1dee48edbee14e252091c7ac25dc56ac5cd5a
353
352
2022-09-26T17:53:23Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc .
{{SITENAME}} is a project to create a wiki dedicated to astronomy.
'''Quick List'''
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
70f13f6c6343f47d8f3a2f1065b77da20aef1801
Main Page
0
1
354
353
2022-09-26T18:05:17Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc .
{{SITENAME}} is a project to create a wiki dedicated to astronomy.
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
{{search box
|root= /
|search-break=<yes|no>
|search-width=number
|search-button-label=text
}}
040e139986fc09d89a2baa4b82ad1afe5434a5a3
355
354
2022-09-26T18:05:38Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc .
{{SITENAME}} is a project to create a wiki dedicated to astronomy.
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
4322d04b76ad693af8433b43daf8230add9d495f
356
355
2022-09-26T18:07:01Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It tries to explains the origin and end of Universe
'''{{SITENAME}}''' is a project to create a wiki dedicated to astronomy.
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
0f0ddf380ea7452c90c0a6215e2ca990ade5e8b3
357
356
2022-10-05T06:59:09Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy.
Note: Project is in Development
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
aeebae5c26bc6cf2b25db12ed6d0b249762f01e8
358
357
2022-10-05T07:01:22Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy.
<br>
{{Box-round|title=Note|Astrobase is in development}}
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
945d32b551627dd2c7ebf5029bc740a1824b5b19
359
358
2022-10-05T07:03:58Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy.
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
ce22d629555437f3f99f5e9560d7b23fc968cdff
364
359
2023-02-22T10:03:47Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy and will also include Pages about battleships and tanks.
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
4aa8c5a28c7e5204cd7bd6bc5b68b3d81cda0b04
370
364
2023-06-04T06:38:17Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
__FORCETOC__
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
a6ff609cbbbb5fcf41845c84aae87db9e82bfd3a
381
370
2023-07-07T05:10:55Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase Home }}
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
[[File:Logospaceman.png|alt=Logo|thumb]]
[[Category:Main]]
__NOEDITSECTION__
__INDEX__
dc3d7c976652c1cfdab7de03f2a45ef2761e5b33
396
381
2023-07-07T17:53:46Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase}}
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
<!-- Disclaimer: AI generated text are also being used , so if you find any mistake kindly reach The administrator -->
[[File:Logospaceman.png|alt=Logo|thumb]]
[[Category:Main]]
__NOEDITSECTION__
__INDEX__
__FORCETOC__
__NONEWSECTIONLINK__
f4d7045dcaf5417b5f9b0622c7edd8bbfa5b5104
Active Galactic Nucleus
0
167
360
2022-10-09T11:26:15Z
SpaceMan
2
Created page with "===Definition=== active galactic nucleus (AGN) The central region of a distant active galaxy that appears to be a point-like source of intense X-ray or gamma ray emissions. Astrophysicists specu- late that the AGN is caused by the presence of a centrally located, supermassive black hole accreting nearby matter."
wikitext
text/x-wiki
===Definition===
active galactic nucleus (AGN) The central region of a
distant active galaxy that appears to be a point-like source of
intense X-ray or gamma ray emissions. Astrophysicists specu-
late that the AGN is caused by the presence of a centrally
located, supermassive black hole accreting nearby matter.
94a587cb175198d4bfb146195051cfe3b5340345
361
360
2022-10-09T11:27:03Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
==Definition==
Active galactic nucleus (AGN) The central region of a distant active galaxy that appears to be a point-like source of intense X-ray or gamma ray emissions. Astrophysicists specu-
late that the AGN is caused by the presence of a centrally located, supermassive black hole accreting nearby matter.
b64e23dcecf0c0d078ab78f119f16a823960ce1a
SpaceMan:About
4
168
362
2023-02-21T17:17:11Z
SpaceMan
2
About
wikitext
text/x-wiki
Welcome to our astronomy website! Here, you can explore the vast wonders of the universe and satisfy your curiosity about everything that lies beyond our planet. Our website provides a comprehensive and user-friendly platform for anyone who is interested in astronomy, from beginners to advanced stargazers.
NOTE - THIS WEBSITE IS STILL IN DEVELOPMENT AND NEEDS MORE CONTENT. AND YOU ARE WELCOME TO CONTRIBUTE HERE,
THANK YOU
7d46a726aa15c157e73d04ffd066827d8f6f54c9
363
362
2023-02-21T17:18:27Z
SpaceMan
2
Protected "[[SpaceMan:About]]" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
Welcome to our astronomy website! Here, you can explore the vast wonders of the universe and satisfy your curiosity about everything that lies beyond our planet. Our website provides a comprehensive and user-friendly platform for anyone who is interested in astronomy, from beginners to advanced stargazers.
NOTE - THIS WEBSITE IS STILL IN DEVELOPMENT AND NEEDS MORE CONTENT. AND YOU ARE WELCOME TO CONTRIBUTE HERE,
THANK YOU
7d46a726aa15c157e73d04ffd066827d8f6f54c9
Nebulae
0
169
365
2023-03-06T15:23:41Z
SpaceMan
2
Created page with "**Definition** A nebula is a vast cloud of interstellar gas and dust within a galaxy, typically illuminated by starlight or other radiation sources. Nebulae come in a variety of shapes and sizes, from small, dense regions of gas and dust to massive, diffuse clouds that stretch across thousands of light-years. Some nebulae are the birthplace of new stars, while others are the remnants of stars that have died. Nebulae can be observed in different wavelengths, including vi..."
wikitext
text/x-wiki
**Definition**
A nebula is a vast cloud of interstellar gas and dust within a galaxy, typically illuminated by starlight or other radiation sources. Nebulae come in a variety of shapes and sizes, from small, dense regions of gas and dust to massive, diffuse clouds that stretch across thousands of light-years. Some nebulae are the birthplace of new stars, while others are the remnants of stars that have died. Nebulae can be observed in different wavelengths, including visible light, ultraviolet, and infrared, which allows astronomers to study their properties and evolution.
115564120c4cb428695a290cbf6c5aae6b427823
366
365
2023-03-06T15:25:52Z
SpaceMan
2
wikitext
text/x-wiki
#'''Definition'''
A nebula is a vast cloud of interstellar gas and dust within a galaxy, typically illuminated by starlight or other radiation sources. Nebulae come in a variety of shapes and sizes, from small, dense regions of gas and dust to massive, diffuse clouds that stretch across thousands of light-years. Some nebulae are the birthplace of new stars, while others are the remnants of stars that have died. Nebulae can be observed in different wavelengths, including visible light, ultraviolet, and infrared, which allows astronomers to study their properties and evolution.
13abaa5524062a15778039cbcb96b59def7c6e89
367
366
2023-03-06T15:37:21Z
SpaceMan
2
wikitext
text/x-wiki
#'''Definition'''
A nebula is a vast cloud of interstellar gas and dust within a galaxy, typically illuminated by starlight or other radiation sources. Nebulae come in a variety of shapes and sizes, from small, dense regions of gas and dust to massive, diffuse clouds that stretch across thousands of light-years. Some nebulae are the birthplace of new [[star]], while others are the remnants of stars that have died. Nebulae can be observed in different wavelengths, including visible light, ultraviolet, and infrared, which allows astronomers to study their properties and evolution.
#'''Types'''
Emission Nebulae: These are brightly glowing clouds of ionized gas, typically reddish or pinkish in color, that are often associated with young, hot stars. Examples include the famous Orion Nebula and the Lagoon Nebula.
Reflection Nebulae: These are clouds of dust that reflect the light of nearby stars, appearing blue in color. The most well-known example is the Pleiades [[star cluster]].
Planetary Nebulae: These are shells of gas and dust ejected by a dying star in its final stages of life. Despite the name, they have nothing to do with planets. Examples include the Ring Nebula and the Helix Nebula.
Dark Nebulae: These are dense clouds of gas and dust that obscure the light of background stars, appearing as dark patches against the [[Milky Way]]. Examples include the Horsehead Nebula and the Pipe Nebula.
Supernova Remnants: These are the expanding shells of gas and dust left behind by a supernova explosion. Examples include the Crab Nebula and the Veil Nebula.
Molecular Clouds: These are the largest and most massive of all nebulae, consisting of cold, dense gas and dust that is the birthplace of new stars. Examples include the Taurus Molecular Cloud and the Orion Molecular Cloud.
b1e94453fbb7ba1a072ae02c954bccabe7c890a3
368
367
2023-03-06T15:38:19Z
SpaceMan
2
wikitext
text/x-wiki
#'''Definition'''
A nebula is a vast cloud of interstellar gas and dust within a galaxy, typically illuminated by starlight or other radiation sources. Nebulae come in a variety of shapes and sizes, from small, dense regions of gas and dust to massive, diffuse clouds that stretch across thousands of light-years. Some nebulae are the birthplace of new [[star]], while others are the remnants of stars that have died. Nebulae can be observed in different wavelengths, including visible light, ultraviolet, and infrared, which allows astronomers to study their properties and evolution.
===Types===
Emission Nebulae: These are brightly glowing clouds of ionized gas, typically reddish or pinkish in color, that are often associated with young, hot stars. Examples include the famous Orion Nebula and the Lagoon Nebula.
Reflection Nebulae: These are clouds of dust that reflect the light of nearby stars, appearing blue in color. The most well-known example is the Pleiades [[star cluster]].
Planetary Nebulae: These are shells of gas and dust ejected by a dying star in its final stages of life. Despite the name, they have nothing to do with planets. Examples include the Ring Nebula and the Helix Nebula.
Dark Nebulae: These are dense clouds of gas and dust that obscure the light of background stars, appearing as dark patches against the [[Milky Way]]. Examples include the Horsehead Nebula and the Pipe Nebula.
Supernova Remnants: These are the expanding shells of gas and dust left behind by a supernova explosion. Examples include the Crab Nebula and the Veil Nebula.
Molecular Clouds: These are the largest and most massive of all nebulae, consisting of cold, dense gas and dust that is the birthplace of new stars. Examples include the Taurus Molecular Cloud and the Orion Molecular Cloud.
db052bd3eb42b473129b8e050ef0ea7f854f5266
Milky Way
0
170
369
2023-06-04T06:35:05Z
SpaceMan
2
Milky way
wikitext
text/x-wiki
The Milky Way is a barred spiral galaxy that is home to our own [solar system] and numerous other stars. It is estimated to contain between 100 and 400 billion stars, making it one of the largest galaxies in the known universe. [The Milky Way] is approximately 100,000 light-years in diameter and is thought to be about 13.5 billion years old.
The [Milky Way] is named after the band of light that is visible in the night sky, which is caused by the concentration of stars and other celestial objects in the galactic plane. The Milky Way is located in the [Local Group], a cluster of more than 50 galaxies that includes the [Andromeda Galaxy] and the Triangulum Galaxy. The Milky Way and the Andromeda Galaxy are the two largest members of the Local Group, and are expected to collide in about 4.5 billion years.
The Milky Way has a central bar-shaped structure surrounded by four major spiral arms, and several smaller arms and spurs. The central bar is thought to be about 27,000 light-years long and 3,000 light-years wide. The spiral arms regions of enhanced star formation and are named the [Norma Arm], the Scutum-Centaurus Arm, the [Sagittarius Arm], and the [Perseus] Arm.
The Milky Way also contains a supermassive black hole at its center, known as Sagittarius A*. This black hole has a mass of about 4.1 million times that of the Sun and is surrounded by a disk of gas and dust. The black hole is currently in a quiescent state, but is thought to have been more active in the past.
The study of the Milky Way and its structure is an ongoing field of research, with astronomers using a variety of techniques and instruments to explore the galaxy. These include telescopes that observe in the visible, infrared, and radio wavelengths, as well as spacecraft that have been sent to study the galaxy's structure and composition. By studying the Milky Way, astronomers hope to gain a better understanding of the formation and evolution of galaxies, as well as the formation and evolution of our own solar system.
dd1a692bc931f7f86c2a64efafd13a60ecb2caf8
403
369
2023-07-13T03:19:56Z
SpaceMan
2
wikitext
text/x-wiki
[[File:ESO - Milky Way.jpg|alt=Milky way|center|frameless|Milky Way]]
The Milky Way is a barred spiral galaxy that is home to our own [solar system] and numerous other stars. It is estimated to contain between 100 and 400 billion stars, making it one of the largest galaxies in the known universe. [The Milky Way] is approximately 100,000 light-years in diameter and is thought to be about 13.5 billion years old.
The [Milky Way] is named after the band of light that is visible in the night sky, which is caused by the concentration of stars and other celestial objects in the galactic plane. The Milky Way is located in the [Local Group], a cluster of more than 50 galaxies that includes the [Andromeda Galaxy] and the Triangulum Galaxy. The Milky Way and the Andromeda Galaxy are the two largest members of the Local Group, and are expected to collide in about 4.5 billion years.
The Milky Way has a central bar-shaped structure surrounded by four major spiral arms, and several smaller arms and spurs. The central bar is thought to be about 27,000 light-years long and 3,000 light-years wide. The spiral arms regions of enhanced star formation and are named the [Norma Arm], the Scutum-Centaurus Arm, the [Sagittarius Arm], and the [Perseus] Arm.
The Milky Way also contains a supermassive black hole at its center, known as Sagittarius A*. This black hole has a mass of about 4.1 million times that of the Sun and is surrounded by a disk of gas and dust. The black hole is currently in a quiescent state, but is thought to have been more active in the past.
The study of the Milky Way and its structure is an ongoing field of research, with astronomers using a variety of techniques and instruments to explore the galaxy. These include telescopes that observe in the visible, infrared, and radio wavelengths, as well as spacecraft that have been sent to study the galaxy's structure and composition. By studying the Milky Way, astronomers hope to gain a better understanding of the formation and evolution of galaxies, as well as the formation and evolution of our own solar system.
[[Category:Astronomy]]
{{DEFAULTSORT:MilkyWay}}
__FORCETOC__
__INDEX__
fbf0e4b8eafd99ac96792fa93e17a79d46009587
Sun
0
171
371
2023-06-08T07:22:19Z
SpaceMan
2
Created page with "{| class="wikitable" |+Data |Name |Sun , Sol |- |Size |Apple |- |Distance from Earth |1.496×108 km , 1AU |- |Mass |1.9885×1030 kg |} The sun is a star located at the center of the solar system and is the closest star to [[Earth]]. It is a nearly perfect sphere of hot plasma, with internal convective that generates a magnetic field. It has a diameter of approximately 1.39 million kilometers (865,000 miles), which is about 109 times the diameter of Earth. Its mass is abo..."
wikitext
text/x-wiki
{| class="wikitable"
|+Data
|Name
|Sun , Sol
|-
|Size
|Apple
|-
|Distance from Earth
|1.496×108 km , 1AU
|-
|Mass
|1.9885×1030 kg
|}
The sun is a star located at the center of the solar system and is the closest star to [[Earth]]. It is a nearly perfect sphere of hot plasma, with internal convective that generates a magnetic field. It has a diameter of approximately 1.39 million kilometers (865,000 miles), which is about 109 times the diameter of Earth. Its mass is about 330,000 times that of Earth, making up about 99.86% of the total mass of the [[solar system]].
The sun's [[energy]] is generated by [[nuclear fusion]] in its [[core]], where hydrogen is converted into helium. This process releases an enormous amount of energy in the form of light and heat, which is radiated outwards in all directions. The energy generated by the sun is responsible for sustaining life on Earth and driving the planet's climate and weather patterns.
The sun has a complex magnetic field, which can create [[sunspots]], [[solar flares]], and [[coronal mass ejections]]. These events can have a significant impact on Earth's environment, causing disruptions in satellite and telecommunications systems, power grids , and even posing a risk to [[astronauts]] in [[space]].
The sun is also responsible for creating the solar wind, a stream of charged particles that flows outwards from the sun and permeates the entire solar system. This wind plays a crucial role in shaping the planets' magnetospheres and protecting them from harmful [[cosmic radiation]].
The sun is estimated to be about 4.6 billion years old and is expected to continue to shine for another 5 billion years or so before running out of fuel and eventually becoming a white dwarf. Its importance to life on Earth and its influence on the wider universe make it one of the most studied objects in [[astronomy]] and [[astrophysics]].
2453664ba07c3ddb7af72ac35070b4d48b0ce04f
399
371
2023-07-09T09:44:27Z
SpaceMan
2
wikitext
text/x-wiki
{| class="wikitable"
|+Data
|Name
|Sun , Sol
|-
|Galactic Period
|(2.25-2.50)*10<sup>8</sup> yr
|-
|Distance from Earth
|1.496×10<sup>8</sup> km , 1AU
|-
|Mass
|1.9885×10<sup>30</sup> kg
|}
The sun is a star located at the center of the solar system and is the closest star to [[Earth]]. It is a nearly perfect sphere of hot plasma, with internal convective that generates a magnetic field. It has a diameter of approximately 1.39 million kilometers (865,000 miles), which is about 109 times the diameter of Earth. Its mass is about 330,000 times that of Earth, making up about 99.86% of the total mass of the [[solar system]].
The sun's [[energy]] is generated by [[nuclear fusion]] in its [[core]], where hydrogen is converted into helium. This process releases an enormous amount of energy in the form of light and heat, which is radiated outwards in all directions. The energy generated by the sun is responsible for sustaining life on Earth and driving the planet's climate and weather patterns.
The sun has a complex magnetic field, which can create [[sunspots]], [[solar flares]], and [[coronal mass ejections]]. These events can have a significant impact on Earth's environment, causing disruptions in satellite and telecommunications systems, power grids , and even posing a risk to [[astronauts]] in [[space]].
The sun is also responsible for creating the solar wind, a stream of charged particles that flows outwards from the sun and permeates the entire solar system. This wind plays a crucial role in shaping the planets' magnetospheres and protecting them from harmful [[cosmic radiation]].
The sun is estimated to be about 4.6 billion years old and is expected to continue to shine for another 5 billion years or so before running out of fuel and eventually becoming a white dwarf. Its importance to life on Earth and its influence on the wider universe make it one of the most studied objects in [[astronomy]] and [[astrophysics]].
552fd79f4263be376d5e07803d30d0f2f256d9a9
Bohr Atomic Model
0
172
372
2023-07-07T04:42:22Z
SpaceMan
2
Created page with "# Bohr Atomic Model ## Definition '''Given by''' - Neil Bohr To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom. ## Postulates Quantization of angular momentum for the electron moving in any orbit. Quantization** is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization. Quantization of angular momentum sta..."
wikitext
text/x-wiki
# Bohr Atomic Model
## Definition
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
## Postulates
Quantization of angular momentum for the electron moving in any orbit.
Quantization** is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
Quantization of angular momentum states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant ** h/2π**
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
Angular Momentum:
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
---
#### Quantization of Energy
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
## Drawbacks
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
29844ab095c6965d2dc51a338a932abba0a53b82
373
372
2023-07-07T04:49:52Z
SpaceMan
2
Editing
wikitext
text/x-wiki
== Bohr Atomic Model ==
=== Definition: ===
##
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
==== Postulates: ====
## Postulates
Quantization of angular momentum for the electron moving in any orbit.
Quantization** is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
Quantization of angular momentum states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
Angular Momentum:
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
---
#
I
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
#
#
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
9cb501d675b45901fc6e92970d5564defd168d1e
374
373
2023-07-07T04:55:35Z
SpaceMan
2
wikitext
text/x-wiki
Bohot Atomic Model
=== Definition: ===
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
==== Postulates: ====
Quantization of angular momentum for the electron moving in any orbit.
Quantization** is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
Quantization of angular momentum states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
Angular Momentum:
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
9ec90be3ad3a791f1a159a93ad6e9ca9b0ea14b9
375
374
2023-07-07T04:55:57Z
SpaceMan
2
wikitext
text/x-wiki
=== Definition: ===
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
==== Postulates: ====
Quantization of angular momentum for the electron moving in any orbit.
Quantization** is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
Quantization of angular momentum states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
Angular Momentum:
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
c71781ea3859d5cb0f61a5a9f50471d122eef694
376
375
2023-07-07T04:58:35Z
SpaceMan
2
wikitext
text/x-wiki
=== Definition: ===
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
==== Postulates: ====
Quantization of angular momentum for the electron moving in any orbit.
'''Quantization''' is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
'''Quantization of angular momentum''' states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
'''Angular Momentum:'''
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
4a0403334bba64ecc2a73327aaf7187b88689fef
377
376
2023-07-07T05:02:13Z
SpaceMan
2
wikitext
text/x-wiki
=== Definition: ===
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
==== Postulates: ====
Quantization of angular momentum for the electron moving in any orbit.
'''Quantization''' is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
'''Quantization of angular momentum''' states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
'''Angular Momentum:'''
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
<ref>https://en.m.wikipedia.org/wiki/Bohr_model</ref>
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
17ff30a19c81eae5ad5adb8e3f92897d972693d0
379
377
2023-07-07T05:05:38Z
SpaceMan
2
wikitext
text/x-wiki
=== Definition: ===
'''Given by''' - Neil Bohr
To overcome the drawback of [[Rutherford model]], a new model of atom was introduced based on ''atomic spectra'' and is known as Bohr model of atom.
[[File:Bohr atom model.svg.png|thumb|Bohr model ]]
==== Postulates: ====
Quantization of angular momentum for the electron moving in any orbit.
'''Quantization''' is defined as any quantity whose value of magnitude is integral multiple of any constant value is called is quantization.
'''Quantization of angular momentum''' states that for any electron occupying any orbit inside atom is always quantized and is integral multiple of a constant <math>h/2π</math>
where , h - Planck's constant (6.626 * 10<sup>-34</sup> joules second).
'''Angular Momentum:'''
mvr = nh/2π
Where '''m''' denotes ''mass'' '''v''' denotes ''velocity'' and '''r''' denotes ''radius of orbit'' in which electron is present.
Inside atom there are infinite number of orbit each having a fixed constant value of energy but the energy of all orbit are quite different from each other.
As we move away from the nucleus energy of orbit goes on increasing.
The energy of it's infinite orbit is maximum possible and is equal to zero this concludes that energy of electron in any orbit inside atom has negative sign with its magnitude.
An atom inside atom occupies that orbit whose energy is exactly equal to the energy of electron.
An electron occupying its native orbit revolve around the nucleus continuously without absorbing or an emitting any radiation all such orbits are called stationary orbit.
Whenever of a finite frequency radiation provides a finite amount of energy to such an electron it jumps into a higher energy orbit and continues its motion in higher energy orbit called as excited states till supply of energy is maintained.
As soon as supply of energy is stopped electron comes back to its original native state by emitting same frequency radiation.
==== Drawbacks: ====
It does not explain Zeeman's and Stark's effect.
'''Zeeman Effect:''' When spectral line is placed in magnetic field spectral line split up into sublines.
'''Stark Effect:''' if splitting of spectral lines take place in electric field then it is known as Stark effect.
Electron shows phenomena of diffraction and interference which indicates that there is wave nature in electron but there is no explanation of wave nature for electron in his model.
Does not explain the spectrum of multi electron system.
Experimental evidences shows that orbits are composed of suborbits / subshell but in Bohr's model there is no such concept of subshell / suborbit.
Does not explain the spectrum of multielectron system.
<ref>https://en.m.wikipedia.org/wiki/Bohr_model</ref>
[[Category:Chemistry]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
198abf48532cfcda880e78ab32ee2bbdadbdd87c
File:Bohr atom model.svg.png
6
173
378
2023-07-07T05:04:29Z
SpaceMan
2
wikitext
text/x-wiki
Bohr model of atom
907237496d252668981efecc93d326ccd63981e0
Category:Chemistry
14
174
380
2023-07-07T05:07:04Z
SpaceMan
2
Created page with "<ref>https://en.m.wikipedia.org/wiki/Chemistry</ref>"
wikitext
text/x-wiki
<ref>https://en.m.wikipedia.org/wiki/Chemistry</ref>
88420ece0bfc56edc434d3300325efc46f12c52f
Canopus
0
37
382
350
2023-07-07T05:43:07Z
SpaceMan
2
wikitext
text/x-wiki
{{short description|Bright giant star in the constellation of Carina}}
{{Other uses}}
{{Starbox begin
| name=Canopus
}}
{{Starbox image
| image=[[File:Canopus.jpg|255px]]
| caption=An image of Canopus by [[Expedition 6]]
}}
{{Starbox observe
| epoch=J2000
| constell=[[Carina (constellation)|Carina]]
| pronounce={{IPAc-en|k|ə|ˈ|n|oʊ|p|ə|s}}<ref>{{OED|Canopus}}</ref>
| ra={{RA|06|23|57.10988}}<ref name="van Leeuwen2007">{{cite journal | title=Validation of the new Hipparcos reduction | last1=van Leeuwen | first1=F. | journal=Astronomy and Astrophysics | volume=474 | issue=2 | pages=653–664 | date=2007 | arxiv=0708.1752 | bibcode=2007A&A...474..653V | doi=10.1051/0004-6361:20078357 | s2cid=18759600 }} [http://webviz.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b48255b3&-out.add=.&-source=I/311/hip2&recno=30362 Vizier catalog entry ]</ref>
| dec={{DEC|-52|41|44.3810}}<ref name="van Leeuwen2007"/>
| appmag_v=−0.74<ref name="Ducati 2002">{{cite journal | title=Catalogue of Stellar Photometry in Johnson's 11-color system | last1=Ducati | first1=J. R. | journal=CDS/ADC Collection of Electronic Catalogues | volume=2237 | pages=0 | date=2002 | bibcode=2002yCat.2237....0D }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b360304a&-out.add=.&-source=II/237/colors&recno=1155 Vizier catalog entry ]</ref>
}}
{{Starbox character
| type=
| class=A9 II<ref name=perkins>{{cite journal|bibcode=1989ApJS...69..301G|title=The early F-type stars – Refined classification, confrontation with Stromgren photometry, and the effects of rotation|journal=Astrophysical Journal Supplement Series|volume=69|pages=301|last1=Gray|first1=R. O.|last2=Garrison|first2=R. F.|year=1989|doi=10.1086/191315}}</ref><ref>{{cite journal|bibcode=1993ASPC...45...59L|title=A Spectroscopic Study of High Galactic Latitude F Supergiant Stars|journal=Luminous High-Latitude Stars. The International Workshop on Luminous High-Latitude Stars|volume=45|pages=59|last1=Lopez-Cruz|first1=O.|last2=Garrison|first2=R. F.|year=1993}}</ref>
| b-v=+0.15<ref name="Ducati 2002"/>
| u-b=+0.10<ref name="Ducati 2002"/>
| variable=
}}
{{Starbox astrometry
| radial_v={{val|20.3|0.5}}<ref name="Gontcharov 2007">{{cite journal | title=Pullkovo Compilation of Radial Velocities for 39495 Hipparcos stars in a common system | last1=Gontcharov | first1=G. A. | journal=Astronomy Letters | volume=32 | issue=1 | pages=759–771 | date=2007 | bibcode=2006AstL...32..759G | doi=10.1134/S1063773706110065|arxiv = 1606.08053 | s2cid=119231169 }} [http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-ref=VIZ53e6b5f60fbd&-out.add=.&-source=III/252/table8&recno=9232 Vizier catalog entry ]</ref>
| prop_mo_ra=19.93<ref name="van Leeuwen2007"/>
| prop_mo_dec=23.24<ref name="van Leeuwen2007"/>
| parallax=10.55
| p_error=0.56
| parallax_footnote=<ref name="van Leeuwen2007"/>
| absmag_v=–5.71<ref name=smiljanic2006/>
|arxiv = 1606.08053 }}
{{Starbox detail
| metal_fe=–0.07<ref name=smiljanic2006/>
| mass={{Val|8.0|0.3}}<ref name=vlti>{{cite journal|bibcode=2013MNRAS.434..437C|arxiv=1306.3288|title=Fundamental parameters of 16 late-type stars derived from their angular diameter measured with VLTI/AMBER|journal=Monthly Notices of the Royal Astronomical Society|volume=434|issue=1|pages=437–450|last1=Cruzalèbes|first1=P.|last2=Jorissen|first2=A.|last3=Rabbia|first3=Y.|last4=Sacuto|first4=S.|last5=Chiavassa|first5=A.|last6=Pasquato|first6=E.|last7=Plez|first7=B.|last8=Eriksson|first8=K.|last9=Spang|first9=A.|last10=Chesneau|first10=O.|year=2013|doi=10.1093/mnras/stt1037|s2cid=49573767}}</ref> (2013)<br/>{{val|10.1|0.1}}<ref name=Tetzlaff2011/> (2011)
| radius={{Val|71|4}}<ref name=vlti/> (2013)<br>{{val|73.3|5.2}}<ref name=DomicianoDeSouza>{{cite journal|doi=10.1051/0004-6361/202140478|title=Refined fundamental parameters of Canopus from combined near-IR interferometry and spectral energy distribution|year=2021|last1=Domiciano De Souza|first1=A.|last2=Zorec|first2=J.|last3=Millour|first3=F.|last4=Le Bouquin|first4=J.-B.|last5=Spang|first5=A.|last6=Vakili|first6=F.|journal=Astronomy & Astrophysics|volume=654|pages=A19|arxiv=2109.07153|bibcode=2021A&A...654A..19D|s2cid=237513623}}</ref> (2021)
| gravity={{Val|1.70|0.05}}<ref name=DomicianoDeSouza/>
| rotational_velocity=9<ref name=ayres2018/>
| rotation={{val|298|u=days|p=≥}}<ref name=Testa2004/>
| luminosity=10,700<ref name=vlti/>
| temperature=7,400<ref name=ayres2018>{{cite journal |bibcode=2018ApJ...854...95A |title=Cracking the Conundrum of F-supergiant Coronae |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |year=2018 |volume=854 |issue=2 |page=95 |doi=10.3847/1538-4357/aaa6d7 |arxiv=1802.02552 |s2cid=119101035 }}</ref>
| age_myr = {{val|25.1|2.5}}<ref name=Tetzlaff2011>{{cite journal | title=A catalogue of young runaway Hipparcos stars within 3 kpc from the Sun | last1=Tetzlaff | first1=N. | last2=Neuhäuser | first2=R. | last3=Hohle | first3=M. M. | journal=Monthly Notices of the Royal Astronomical Society | volume=410 | issue=1 | pages=190–200 | date=January 2011 | doi=10.1111/j.1365-2966.2010.17434.x | arxiv=1007.4883 | bibcode=2011MNRAS.410..190T | s2cid=118629873 }}</ref>
}}
{{Starbox catalog
| names={{odlist | name=Suhayl | name2=Suhel | name3=Suhail | B=α Carinae | CPD=−52°1941 | FK5=245 | HD=45348 | HIP=30438 | HR=2326 | SAO=234480| GC=8302 }}<ref name=SIMBAD>{{cite simbad | title=alf Car | access-date=2019-03-09 }}</ref>
}}
{{Starbox reference
| Simbad=canopus
}}
{{Starbox end}}
'''Canopus''' is the brightest star in the southern [[constellation]] of [[Carina (constellation)|Carina]] and the [[list of brightest stars|second-brightest star]] in the [[night sky]]. It is also [[Bayer designation|designated]] '''α Carinae''', which is [[Latinisation of names|Latinised]] to '''Alpha Carinae'''. With a [[visual apparent magnitude]] of −0.74, it is outshone only by [[Sirius]]. Located around {{val|310|ul=light-years}} from the [[Sun]], Canopus is a [[bright giant]] of [[spectral type A9]], so it is essentially white when seen with the naked eye. It has a luminosity over 10,000 times the [[luminosity of the Sun]], is eight times as [[mass of the Sun|massive]], and has expanded to 71 times the [[Sun's radius]]. Its enlarged [[photosphere]] has an [[effective temperature]] of around {{val|7,400|fmt=commas|u=K}}. Canopus is undergoing [[stellar core|core]] [[helium fusion|helium burning]] and is currently in the so-called [[blue loop]] phase of its [[stellar evolution|evolution]], having already passed through the [[red-giant branch]] after exhausting the hydrogen in its core. Canopus is a [[X-ray astronomy|source of X-rays]], which are likely being emitted from its [[stellar corona|corona]].
The prominent appearance of Canopus means it has been the subject of mythological lore among many ancient peoples. Its proper name is generally considered to originate from the [[Greek mythology|mythological]] [[Canopus (mythology)|Canopus]], who was a navigator for [[Menelaus]], king of [[Sparta]]. The [[acronychal rising]] marked the date of the Ptolemaia festival in Egypt. In ancient India, it was named [[Agastya]] after the revered [[Vedas|Vedic]] sage. For Chinese astronomers, it was known as the [[Old Man of the South Pole]].
==Nomenclature==
The name ''Canopus'' is a Latinisation of the [[Ancient Greek]] name Κάνωβος/Kanôbos, recorded in Claudius Ptolemy's ''[[Almagest]]'' (c.150 AD). Eratosthenes used the same spelling.<ref name="ridpathCr"/> Hipparchos wrote it as Κάνωπος. [[John Flamsteed]] wrote Canobus,<ref>{{cite book|last=Flamsteed|first=John|title=Atlas coelestis|location=London, United Kingdom|date=1729|pages=Constellation Map of Southern Hemisphere|url=http://lhldigital.lindahall.org/u?/astro_atlas,1191}}</ref> as did [[Edmond Halley]] in his 1679 ''Catalogus Stellarum Australium''.<ref name="Halley 1679">{{cite book|last=Halley|first=Edmond|title=Catalogus stellarum australium; sive, Supplementum catalogi Tychenici, exhibens longitudines et latitudines stellarum fixarum, quae, prope polum Antarcticum sitae, in horizonte Uraniburgico Tychoni inconspicuae fuere, accurato calculo ex distantiis supputatas, & ad annum 1677 completum correctas...Accedit appendicula de rebus quibusdam astronomicis|publisher=T. James|location=London|date=1679|pages=30|url=http://babel.hathitrust.org/cgi/pt?id=mdp.39015007000170;view=1up;seq=41;size=150}}</ref> The name has two possible derivations, both listed in [[Richard Hinckley Allen]]'s seminal ''[[Star Names: Their Lore and Meaning]]''.
* [[Argo Navis]] was the ship used by [[Jason]] and the Argonauts in the legend of the [[Trojan War]]. The brightest star in the constellation was given the name of a ship's pilot from another Greek legend: [[Canopus (mythology)|Canopus]], pilot of [[Menelaus]]' ship on his quest to retrieve [[Helen of Troy]] after she was taken by [[Paris (mythology)|Paris]].<ref name="hinkley63">{{cite book|first=Richard Hinckley|last=Allen|author-link=Richard Hinckley Allen|date=1963|orig-year=1899|title=Star Names: Their Lore and Meaning|pages=[https://archive.org/details/starnamestheirlo00alle/page/67 67–72]|edition=Revised|publisher=Dover Publications|location=New York|isbn=0-486-21079-0|url-access=registration|url=https://archive.org/details/starnamestheirlo00alle/page/67}}</ref>
* A ruined ancient Egyptian port named [[Canopus, Egypt|Canopus]] lies near the mouth of the [[Nile]], site of the [[Battle of the Nile]]. It is speculated that its name is derived from the Egyptian [[Coptic language|Coptic]] ''Kahi Nub'' ("Golden Earth"), which refers to how Canopus would have appeared near the horizon in [[ancient Egypt]], reddened by atmospheric extinction from that position.<ref name="hinkley63"/><ref name=lynn1905>{{cite journal |bibcode=1905Obs....28..289L |title=The brightest fixed star and its name |last1=Lynn |first1=W. T. |journal=The Observatory |year=1905 |volume=28 |page=289 }}</ref>
In 2016, the [[International Astronomical Union]] organized a [[IAU Working Group on Star Names|Working Group on Star Names]] (WGSN) to catalog and standardize proper names for stars.<ref name="WGSN">{{cite web | url=https://www.iau.org/science/scientific_bodies/working_groups/280/ | title=IAU Working Group on Star Names (WGSN) | website=iau.org | publisher=[[International Astronomical Union]] | access-date=22 May 2016}}</ref> The WGSN's first bulletin of July 2016 included a table of the first two batches of names approved by the WGSN, which included ''Canopus'' for this star.<ref name="WGSN1">{{cite web | url=https://www.iau.org/static/science/scientific_bodies/working_groups/280/WGSN_bulletin1.pdf | title=Bulletin of the IAU Working Group on Star Names, No. 1 | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06 }}</ref> Canopus is now included in the ''IAU Catalog of Star Names''.<ref name="IAU-CSN">{{cite web | url=https://www.iau.org/public/themes/naming_stars/ | title=IAU Catalog of Star Names | website=iau.org | publisher=International Astronomical Union | access-date=2020-09-06}}</ref>
Canopus traditionally marked the rudder of the ship [[Argo Navis]].<ref>{{cite journal | title = On Frederick de Houtman's Catalogue of Southern Stars, and the Origin of the Southern Constellations | last1= Knobel|first1=E. B. |journal = [[Monthly Notices of the Royal Astronomical Society]] | volume= 77| issue= 5 | pages=414–432 [422] | bibcode = 1917MNRAS..77..414K |date=1917 | doi=10.1093/mnras/77.5.414| doi-access=free }}</ref> German celestial cartographer [[Johann Bayer]] gave it—as the brightest star in the constellation—the [[Bayer designation|designation]] of ''α Argus'' ([[Latinisation of names|Latinised]] to ''Alpha Argus'') in 1603. In 1763, French astronomer [[Nicolas Louis de Lacaille]] divided the huge constellation into three smaller ones,<ref name=Glass2012>{{cite book | title=Nicolas-Louis De La Caille, Astronomer and Geodesist | first=Ian Stewart | last=Glass | date=November 17, 2012 | page=73 | isbn=9780191649608 | publisher=OUP Oxford | url=https://www.google.com/books/edition/Nicolas_Louis_De_La_Caille_Astronomer_an/eZjlHAIBeRAC?hl=en&gbpv=1&pg=PT73 }}</ref> and hence Canopus became ''α Carinae'' ([[Latinisation of names|Latinised]] to ''Alpha Carinae''). It is listed in the [[Bright Star Catalogue]] as HR 2326, the [[Henry Draper Catalogue]] as HD 45348, and the [[Hipparcos catalogue]] as HIP 30438.<ref name=SIMBAD/> Flamsteed did not number this southern star, but [[Benjamin Apthorp Gould]] gave it the number 7 (7 G. Carinae) in his ''Uranometria Argentina''.<ref name=Gould1878>{{cite journal | title=Uranometria Argentina: Brightness and position of every fixed star, down to the seventh magnitude, within one hundred degrees of the South Pole; with atlas | last=Gould | first=Benjamin Apthorp | journal=Resultados del Observatorio Nacional Argentino | volume=1 | page=140 | date=1878 | bibcode=1879RNAO....1....1G }}</ref>
An occasional name seen in English is ''Soheil'', or the feminine Soheila; in Turkish is ''Süheyl'', or the feminine Süheyla, from the Arabic name for several bright stars, سهيل ''suhayl'',<ref name="hinkley63"/> and Canopus was known as Suhel {{IPAc-en|'|s|uː|h|E|l}} in medieval times.<ref name=kunitzsch/> Alternative spellings include Suhail, Souhail, Suhilon, Suheyl, Sohayl, Suhayil, Shoel, Sohil, Soheil, Sahil, Suhayeel, Sohayil, Sihel, and Sihil.<ref name="hinkley63"/> An alternative name was ''Wazn'' "weight" or ''Haḍar'' "ground", possibly related to its low position near the horizon.<ref name="hinkley63"/> Hence comes its name in the ''[[Alfonsine tables]]'', Suhel ponderosus, a Latinization of ''Al Suhayl al Wazn''.<ref name="hinkley63"/> Its Greek name was revived during the [[Renaissance]].<ref name=kunitzsch>{{cite book |last1=Kunitzsch|first1=Paul |last2=Smart|first2=Tim |date = 2006|title = A Dictionary of Modern star Names: A Short Guide to 254 Star Names and Their Derivations |edition = 2nd rev. |publisher = Sky Publishing Corporation |location = Cambridge, Massachusetts |isbn = 978-1-931559-44-7 |page = 23}}</ref>
==Observation==
[[File:Carina constellation map.svg|thumb|left|The constellation [[Carina (constellation)|Carina]] with Canopus towards the right (west)]]
The Spanish Muslim astronomer [[Ibn Rushd]] went to [[Marrakesh]] (in Morocco) to observe the star in 1153, as it was invisible in his native [[Córdoba, Spain|Córdoba]], [[Al-Andalus]]. He used the different visibility in different latitudes to argue that the [[Spherical Earth|earth is round]], following [[Spherical Earth#Aristotle|Aristotle's argument]] which held that such an observation was only possible if the earth was a relatively small sphere.<ref name=ibn_rushd>{{cite encyclopedia|first1=Juan|last1=Vernet|author-link1=Juan Vernet|first2=Julio|last2=Samsó|author-link2=Julio Samsó |title=The development of Arabic science in Andalusia |page=264|editor=[[Roshdi Rashed]]|encyclopedia=Encyclopedia of the History of Arabic Science | date=1996|publisher=Routledge|isbn=978-0-415-12410-2|oclc=912501823}}</ref>
English explorer [[Robert Hues]] brought Canopus to the attention of European observers in his 1592 work ''Tractatus de Globis'', along with [[Achernar]] and [[Alpha Centauri]], noting:<blockquote>"Now, therefore, there are but three [[First-magnitude star|Stars of the first magnitude]] that I could perceive in all those parts which are never seene here in England. The first of these is that bright Star in the sterne of [[Argo Navis|Argo]] which they call Canobus. The second is in the end of [[Eridanus (constellation)|Eridanus]]. The third is in the right foote of the [[Centaurus|Centaure]]."<ref>Knobel, p. 416.</ref></blockquote>
[[File:Vela and Surrounding Constellations (ground-based image).jpg|right|thumb|Wide angle view showing Canopus and other prominent stars with the Milky Way|alt=A field of stars against the Milky Way background with the prominent stars and constellations labelled]]
In the [[Southern Hemisphere]], Canopus and [[Sirius]] are both visible high in the sky simultaneously, and reach a [[meridian (astronomy)|meridian]] just {{val|21|u=minutes}} apart. Brighter than [[first-magnitude star|first magnitude]], Canopus can be seen by naked eye in the early twilight. Mostly visible in mid to late summer in the Southern Hemisphere, Canopus [[Culmination|culminates]] at midnight on December 27,<ref name="motz" /> and at 9 PM on February 11.<ref name="Schaaf257">Schaaf, p. 257.</ref>
When seen from latitudes south of {{DEC|37|18}} S, Canopus is a [[circumpolar star]]. Since Canopus is so far south in the sky, it never rises in mid- to far-northern latitudes; in theory the northern limit of visibility is latitude {{DEC|37|18}} north. This is just south of [[Athens]], [[Richmond, Virginia]] (USA), and [[San Francisco]], and very close to [[Seville]] and [[Agrigento]]. It is almost exactly the latitude of [[Lick Observatory]] on [[Mount Hamilton (California)|Mt. Hamilton, California]], from which it is readily visible because of the effects of elevation and [[atmospheric refraction]], which add another degree to its apparent altitude. Under ideal conditions, it can be spotted as far north as latitude {{DEC|37|31}} from the Pacific coast.<ref>D. Gieringer, "Exploring the Tropic of Canopus", ''Astronomy'', December 1985, p.24.</ref> Another northernmost record of visibility came from [[Mount Nemrut]] in Turkey, latitude {{DEC|37|59}}.<ref>{{cite web |last1=Tezel |first1=Tunç |author-link=Tunç Tezel |url=http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |title=Zodiacal Light and Nemrut Heritage |work=The World At Night (TWAN) |access-date=17 March 2014 |date=8 Oct 2013 |archive-url=https://web.archive.org/web/20140317134955/http://www.twanight.org/newTWAN/photos.asp?ID=3004572 |archive-date=17 March 2014 |url-status=dead }}</ref> It is more easily visible in places such as the Gulf Coast and Florida, and the island of [[Crete]] (Greece) where the best season for viewing it around 9 p.m. is during late January and early February.<ref name="motz">{{cite book|last1=Motz|first1=Lloyd|last2=Nathanson|first2=Carol|title=The Constellations: An Enthusiast's Guide to the Night Sky|publisher=Aurum Press|location=London, United Kingdom|date=1991|pages=376–77|isbn=1-85410-088-2}}</ref>
Canopus has a B–V [[color index]] of +0.15—where 0 is a blue-white—indicating it is essentially white, although it has been described as yellow-white. Canopus' spectral type has been given as F0 and the incrementally warmer A9. It is less yellow than [[Altair]] or [[Procyon]], with indices measured as 0.22 and 0.42, respectively.<ref name=Hoffleit1991>{{cite book | title=Bright Star Catalogue | edition=5th Revised | last1=Hoffleit | first1=D. | last2=Warren Jr. | first2=W. H. | date=1991 | publisher=[[Centre de Données astronomiques de Strasbourg|CDS]] }}</ref> Some observers may have perceived Canopus as yellow-tinged because it is low in the sky and hence subject to atmospheric effects.<ref name="Schaaf112">Schaaf, pp. 112–13.</ref> [[Patrick Moore]] said that it never appeared anything but white to him.<ref name="moore2000">{{cite book | first1=Patrick | last1=Moore | title=Exploring the night sky with binoculars | edition=4th | publisher=Cambridge University Press | year=2000 | isbn=9780521793902 | page=[https://archive.org/details/exploringnightsk00moor/page/69 69] | url=https://archive.org/details/exploringnightsk00moor| url-access=registration }}</ref> The [[bolometric correction]] for Canopus is 0.00,<ref name=smiljanic2006/> indicating that the visual [[absolute magnitude]] and bolometric absolute magnitude are equal.
Canopus was previously proposed to be a member of the [[Scorpius–Centaurus association]], however it is not located near the subgroups of that association, and has not been included as a Sco-Cen member in kinematic studies that used [[Hipparcos]] astrometric data.<ref name="deZeeuw">{{cite journal|last1=de Zeeuw|first1=P.T. |last2=Hoogerwerf|first2=R. |last3=de Bruijne|first3=J.H.J |last4=Brown|first4=A.G.A |last5=Blaauw|first5=A. |date=1999|title=A HIPPARCOS Census of the Nearby OB Associations |journal=The Astronomical Journal |volume=117 |issue=1 |pages=354–399|bibcode=1999AJ....117..354D |doi=10.1086/300682|arxiv = astro-ph/9809227 |s2cid=16098861 }}</ref> Canopus is not thought to be a member of any nearby young stellar groups.<ref name=mamajek>{{cite journal | url=https://figshare.com/articles/Canopus_B_A_Candidate_Common_Proper_Motion_Companion_to_the_Second_Brightest_Star/1132696 | title=Canopus B: A Candidate Common Proper Motion Companion to the Second Brightest Star | last=Mamajek | first=Eric | year=2014 | publisher=Figshare | doi=10.6084/m9.figshare.1132696.v3 | access-date=2020-09-10 }}</ref> In 2014, astronomer Eric Mamajek reported that an extremely magnetically active M dwarf (having strong coronal X-ray emission), 1.16 degrees south of Canopus, appears to share a [[common proper motion]] with Canopus. The projected separation of the M dwarf 2MASS J06234738-5351131 ("Canopus B") is approximately 1.9 parsecs. However, despite this large separation, it is still within the estimated tidal radius (2.9 parsecs) for the massive star Canopus.<ref name="mamajek"/>
No star closer than Canopus is more luminous than it, and it has been the brightest star in Earth's night sky during three epochs over the past four million years. Other stars appear brighter only during relatively temporary periods, during which they are passing the Solar System much closer than Canopus. About 90,000 years ago, [[Sirius]] moved close enough that it became brighter than Canopus, and that will remain so for another 210,000 years. But in 480,000 years, as Sirius moves further away and appears fainter, Canopus will once again be the brightest, and will remain so for a period of about 510,000 years.<ref name="tomkin98">{{cite journal|last=Tomkin|first=Jocelyn|date=April 1998|title=Once and Future Celestial Kings|journal=Sky and Telescope|volume=95|issue=4|pages=59–63|bibcode=1998S&T....95d..59T}}</ref><!-- this all comes from same paper -->
===Role in navigation===
The southeastern wall of the [[Kaaba]] in [[Mecca]] is aligned with the rising point of Canopus, and is also named ''Janūb''.<ref>{{cite book|author=George Nicholas Atiyeh|title=The Book in the Islamic World: The Written Word and Communication in the Middle East|url=https://books.google.com/books?id=t4LEfpCW_kQC|date=1 January 1995|publisher=SUNY Press|isbn=978-0-7914-2473-5}}</ref> The [[Negev Bedouin|Bedouin]] people of the [[Negev]] and [[Sinai Peninsula|Sinai]] knew Canopus as ''Suhayl'', and used it and [[Polaris]] as the two principal stars for navigation at night. Because it disappears below the horizon in those regions, it became associated with a changeable nature, as opposed to always-visible Polaris, which was circumpolar and hence 'steadfast'.<ref>{{cite journal |last=Bailey |first=Clinton |date=1974 |title=Bedouin Star-Lore in Sinai and the Negev |journal=Bulletin of the School of Oriental and African Studies, University of London |volume=37 |issue=3 |pages=580–96 |type=abstract |doi=10.1017/S0041977X00127491 |jstor=613801|s2cid=131527348 }}</ref>
The south [[celestial pole]] can be approximately located using Canopus and another bright star, [[Achernar]], as the three make an [[equilateral triangle]]. Canopus sits on an imaginary line that extends {{DEC|36}} one way to Sirius and {{DEC|37}} to the south celestial pole.<ref>{{Cite book| last1 = Heifetz| first1 = Milton| last2 = Tirion| first2 = Wil| title = A Walk Through the Heavens: A Guide to Stars and Constellations and Their Legends | date = 2007| publisher = [[Cambridge University Press]]| location = Cambridge | page = 38 | isbn=978-1-139-46138-2}}</ref>
Canopus's brightness and location well off the [[ecliptic]] make it useful for space navigation. Many spacecraft carry a special camera known as a "Canopus [[star tracker|Star Tracker]]" plus a Sun sensor for [[Orientation (geometry)|attitude]] determination. [[Mariner 4]] used Canopus for [[Spin-stabilisation|second axis stabilisation]] (after locking on the Sun) in 1964, the first time a star had been used.<ref>{{cite book |last1=United States. National Aeronautics and Space Administration. Scientific and Technical Information Division |title=Astronautics and Aeronautics, 1964: Chronology on Science, Technology and Policy |date=1965 |publisher=Scientific and Technical Information Division, National Aeronautics and Space Administration |page=398 |url=https://books.google.com/books?id=ckkCAAAAIAAJ&pg=PA398}}</ref>
==Spectrum==
Canopus was little-studied by western scientists before the 20th century. It was given a spectral class of F in 1897, an early use of this extension to [[Secchi class]] I, applied to those stars where the hydrogen lines are relatively weak and the [[calcium K line]] relatively strong.<ref>{{cite journal |bibcode=1897ApJ.....6..349P |title=Spectra of bright southern stars |last1=Pickering |first1=E. C. |last2=Cannon |first2=A. J. |journal=The Astrophysical Journal |year=1897 |volume=6 |page=349 |doi=10.1086/140407 }}</ref> It was given as a standard star of F0 in the [[Henry Draper Catalogue]], with the spectral type F0 described as having hydrogen lines half the strength of an A0 star and the calcium K line three times as strong as Hδ.<ref name=hd>{{cite journal |bibcode=1918AnHar..92....1C |title=The Henry Draper catalogue : 4h, 5h and 6h |last1=Cannon |first1=Annie Jump |last2=Pickering |first2=Edward Charles |journal=Annals of Harvard College Observatory |year=1918 |volume=92 |page=1 }}</ref> American astronomer [[Jesse L. Greenstein|Jesse Greenstein]] was interested in stellar spectra and used the newly built [[Otto Struve Telescope]] at [[McDonald Observatory]] to analyze the star's spectrum in detail.<ref>{{cite book |last1=Trimble |first1=Virginia | first2= Thomas R. |last2=Williams | first3= Katherine | last3=Bracher| first4= Richard | last4=Jarrell| first5=Jordan D.| last5= Marché| first6=F. Jamil | last6=Ragep |title=Biographical Encyclopedia of Astronomers |date=2007 |publisher=Springer Science & Business Media |location=New York, New York |isbn=978-0-387-30400-7 |page=438 |url=https://books.google.com/books?id=t-BF1CHkc50C&pg=PA438}}</ref> In a 1942 paper, he reported that the spectrum is dominated by strong broad hydrogen lines. There are also [[absorption line]]s of carbon, nitrogen, oxygen, sulphur, iron, and many ionised metals.<ref name=greenstein1942>{{cite journal |bibcode=1942ApJ....95..161G |title=The Spectrum of α Carinae |last1=Greenstein |first1=Jesse L. |journal=The Astrophysical Journal |year=1942 |volume=95 |page=161 |doi=10.1086/144382 }}</ref> It was studied in the [[ultraviolet]] by an early astronomical satellite, [[Gemini XI]] in 1966. The UV spectra were considered to be consistent with an F0 [[Supergiant star|supergiant]] having a temperature of {{val|6,900|fmt=commas|u=K}}, the accepted parameters for Canopus at the time.<ref name=kondo1970>{{cite journal |bibcode=1970ApJ...159..927K |title=Ultraviolet Spectrophotometry of Canopus from Gemini XI |last1=Kondo |first1=Y. |last2=Henize |first2=K. G. |last3=Kotila |first3=C. L. |journal=The Astrophysical Journal |year=1970 |volume=159 |page=927 |doi=10.1086/150370 }}</ref> New Zealand-based astronomers [[John Hearnshaw]] and Krishna Desikachary examined the spectrum in greater detail, publishing their results in 1982.<ref>{{cite journal |title=The spectrum of Canopus | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 198 | year= 1982 | issue= 2 | pages= 311–320 | doi= 10.1093/mnras/198.2.311 | bibcode=1982MNRAS.198..311H| doi-access= free }}</ref><ref>{{cite journal |title=The spectrum of Canopus II - Analysis and composition | last1= Hearnshaw | first1= J. B.| last2= Desikachary | first2= K. | journal= Monthly Notices of the Royal Astronomical Society | volume= 201 | year= 1982 | issue= 3 | pages= 707–721 | doi= 10.1093/mnras/201.3.707 | bibcode=1982MNRAS.201..707D| doi-access= free }}</ref>
When [[luminosity class]]es were added to the MK spectral classification scheme, Canopus was assigned class Iab indicating an intermediate luminosity supergiant. This was based on the relative strengths of certain spectral lines understood to be sensitive to the luminosity of a star.<ref name=devaucoleurs>{{cite journal|title=Spectral types and luminosities of B, A and F southern stars|author=de Vaucouleurs, A.|journal=Monthly Notices of the Royal Astronomical Society|volume=117|page=449|date=1957|issue=4|bibcode=1957MNRAS.117..449D|doi=10.1093/mnras/117.4.449|doi-access=free}}</ref> In the [[Bright Star Catalogue]] 5th edition it is given the spectral class F0II, the luminosity class indicating a [[bright giant]].<ref name=bsc>{{cite book |bibcode=1991bsc..book.....H |year=1991 |title=The Bright star catalogue |last1=Hoffleit |first1=Dorrit |last2=Jaschek |first2=Carlos }}</ref> [[Balmer line]] profiles and oxygen line strengths indicate the size and luminosity of Canopus.<ref name=kovtyukh2012>{{cite journal |bibcode=2012MNRAS.423.3268K |title=Accurate luminosities from the oxygen λ7771-4 Å triplet and the fundamental parameters of F-G supergiants |last1=Kovtyukh |first1=V. V. |last2=Gorlova |first2=N. I. |last3=Belik |first3=S. I. |journal=Monthly Notices of the Royal Astronomical Society |year=2012 |volume=423 |issue=4 |page=3268 |doi=10.1111/j.1365-2966.2012.21117.x |arxiv=1204.4115 |s2cid=118683158 }}</ref>
When the effects of stellar rotation speed on spectral lines are accounted for, the MK spectral class of Canopus is adjusted to A9II.<ref name=perkins/> Its spectrum consists mostly of absorption lines on a visible [[continuous spectrum|continuum]], but some emission has been detected. For example, the [[calcium K line]] have weak emission wings on each side of the strong central absorption line, first observed in 1966. The emission line profiles are usually correlated with the luminosity of the star as described by the [[Wilson-Bappu effect]], but in the case of Canopus they indicate a luminosity much lower than that calculated by other methods.<ref name=warner1966>{{cite journal|title=CA II emission in the spectrum of Canopus|journal=The Observatory |volume=86 |pages=82|date=April 1966|last=Warner |first=B. |bibcode=1966Obs....86...82W }}</ref> More detailed observations have shown that the emission line profiles are variable and may be due to [[plage (astronomy)|plage]] areas on the surface of the star. Emission can also be found in other lines such as the h and k lines of ionised magnesium.<ref name=bappu1984>{{cite journal |bibcode=1984BASI...12..196B |title=CA II K emission in Canopus |last1=Bappu |first1=M. K. V. |last2=Mekkaden |first2=M. V. |last3=Rao |first3=N. K. |journal=Bulletin of the Astronomical Society of India |year=1984 |volume=12 |page=196 }}</ref>
==Distance==
Before the launch of the [[Hipparcos]] satellite telescope, distance estimates for Canopus varied widely, from 96 [[light-year]]s to 1200 light-years. The closer distance was derived from parallax measurements of around {{val|33|ul=mas}}.<ref name=vandekamp1943>{{cite journal |title=Note on the Parallax of Canopus|journal=Popular Astronomy |volume=51 |date=1943 |page=172 |last=van de Kamp |first=Peter|bibcode=1943PA.....51..172V }}</ref> The larger distance derives from the assumption of a very bright [[absolute magnitude]] for Canopus.<ref name=vanzyl>{{cite book|author=J.E. van Zyl|title=Unveiling the Universe: An Introduction to Astronomy|url=https://books.google.com/books?id=Cj7uBwAAQBAJ&pg=PA184|date=6 December 2012|publisher=Springer Science & Business Media|isbn=978-1-4471-1037-8|pages=184–}}</ref>
Hipparcos established Canopus as being {{val|310|u=light-years}} ({{val|95|ul=parsecs}}) from the [[Solar System]]; this is based on its 2007 [[parallax]] measurement of {{Val|10.43|0.53|ul=mas}}.<ref name="van Leeuwen2007"/> At 95 parsecs, the [[interstellar extinction]] for Canopus is low at 0.26 magnitudes.<ref name=DomicianoDeSouza/> Canopus is too bright to be included in the normal observation runs of the [[Gaia satellite]] and there is no published Gaia parallax for it.<ref name=dr2>{{cite DR2}}</ref>
At present the star is drifting further away from the Sun with a [[radial velocity]] of 20 km/s. Some 3.1 million years ago it made the closest approach to the Sun at a distance of about {{convert|52.87|pc|ly|0|adj=ri0|order=flip|abbr=on|lk=off}}. Canopus is orbiting the Milky Way with a heliocentric velocity of 24.5 km/s and a low [[orbital eccentricity|eccentricity]] of 0.065.<ref name=Anderson2012>{{citation | last1=Anderson | first1=E. | last2=Francis | first2=Ch. | title=XHIP: An extended hipparcos compilation | journal=Astronomy Letters | volume=38 | issue=5 | pages=331 | year=2012 | bibcode=2012AstL...38..331A | arxiv=1108.4971 | doi=10.1134/S1063773712050015 | s2cid=119257644 | postscript=. }}</ref>
==Physical characteristics==
[[File:Constellation_Carina.jpg|thumb|right|upright|Canopus is the brightest star in the constellation of Carina (top).]]
The [[absorption line]]s in the spectrum of Canopus shift slightly with a period of {{val|6.9|u=days}}. This was first detected in 1906 and the [[doppler effect|Doppler]] variations were interpreted as orbital motion.<ref name=curtis1907>{{cite journal |bibcode=1907PASP...19R.259C |title=The orbits of the spectroscopic binaries alpha Carinae, kappa Velorum, and alpha Pavonis |last1=Curtis |first1=H. D. |journal=Publications of the Astronomical Society of the Pacific |year=1907 |volume=19 |page=259 |doi=10.1086/121781 }}</ref> An orbit was even calculated, but no such companion exists and the small radial velocity changes are due to movements in the atmosphere of the star. The maximum observed [[radial velocities]] are only 0.7 to {{val|1.6|ul=km/s}}. Canopus also has a magnetic field that varies with the same period, detected by the [[Zeeman splitting]] of its spectral lines.<ref name=weiss1986>{{cite journal |bibcode=1986A&A...160..243W | title=The magnetic field of Canopus | last=Weiss | first=W. W. | journal= Astronomy and Astrophysics |volume= 160|pages= 243–250 | year=1986}}</ref> Canopus is bright at [[microwave]] wavelengths, one of the few F-class stars to be detected by radio.<ref name=gudel2002>{{cite journal |bibcode=2002ARA&A..40..217G |title=Stellar Radio Astronomy: Probing Stellar Atmospheres from Protostars to Giants |last1=Güdel |first1=Manuel |journal=Annual Review of Astronomy and Astrophysics |year=2002 |volume=40 |pages=217–261 |doi=10.1146/annurev.astro.40.060401.093806 |arxiv=astro-ph/0206436 |s2cid=53633983 }}</ref> The [[rotation period]] of the star is not accurately known, but may be over three hundred days.<ref name=Testa2004>{{cite journal | title=The Density of Coronal Plasma in Active Stellar Coronae | last1=Testa | first1=Paola | last2=Drake | first2=Jeremy J. | last3=Peres | first3=Giovanni | journal=The Astrophysical Journal | volume=617 | issue=1 | pages=508–530 | date=December 2004 | doi=10.1086/422355 | arxiv=astro-ph/0405019 | bibcode=2004ApJ...617..508T | s2cid=17532089 }}</ref> The [[projected rotational velocity]] has been measured at 9 km/s.<ref name=ayres2018/>
An early [[Interferometry|interferometric]] measurement of its [[angular diameter]] in 1968 gave a [[Limb darkening|limb-darkened]] value of {{val|6.86|ul=mas}}, close to the accepted modern value.<ref>{{cite journal |bibcode=1968ARA&A...6...13B |title=Measurement of Stellar Diameters |last1=Brown |first1=R. Hanbury |journal=Annual Review of Astronomy and Astrophysics |year=1968 |volume=6 |page=13 |doi=10.1146/annurev.aa.06.090168.000305 }}</ref> [[Very-long-baseline interferometry]] has been used to calculate Canopus' angular diameter at {{val|6.9|ul=mas}}. Combined with distance calculated from its Hipparcos parallax, this gives it a radius of 71 times [[Solar radius|that of the Sun]].<ref name=vlti/> If it were at the centre of the Solar System, it would extend 90% of the way to the orbit of [[Mercury (planet)|Mercury]].<ref name=Kalerstars>{{cite web|url=http://stars.astro.illinois.edu/sow/canopus.html|title=Canopus|last=Kaler|first=Jim|work=Stars|publisher=University of Illinois|access-date=8 July 2012|date=26 June 2009}}</ref> The radius and temperature relative to the Sun means that it is 10,700 times more luminous than the Sun, and its position in the [[H-R diagram]] relative to theoretical [[stellar evolution|evolutionary]] tracks means that it is {{Val|8.0|0.3}} times as massive as the Sun.<ref name=vlti/> Measurements of its shape find a 1.1° departure from spherical symmetry.<ref name=cruzalebes2015>{{cite journal |bibcode=2015MNRAS.446.3277C |title=Departure from centrosymmetry of red giants and supergiants measured with VLTI/AMBER |last1=Cruzalèbes |first1=P. |last2=Jorissen |first2=A. |last3=Chiavassa |first3=A. |last4=Paladini |first4=C. |last5=Rabbia |first5=Y. |last6=Spang |first6=A. |journal=Monthly Notices of the Royal Astronomical Society |year=2015 |volume=446 |issue=4 |page=3277 |doi=10.1093/mnras/stu2382 |doi-access=free }}</ref>
Canopus is a source of [[X-ray astronomy|X-rays]], which are probably produced by its corona, magnetically heated to several million [[Kelvin]]. The temperature has likely been stimulated by fast rotation combined with strong convection percolating through the star's outer layers.<ref name=ness>{{cite journal|bibcode=2004A&A...427..667N|title=On the sizes of stellar X-ray coronae|journal=Astronomy and Astrophysics|volume=427|issue=2|pages=667–683|last1=Ness|first1=J.-U.|last2=Güdel|first2=M.|last3=Schmitt|first3=J. H. M. M.|last4=Audard|first4=M.|last5=Telleschi|first5=A.|year=2004|doi=10.1051/0004-6361:20040504|arxiv = astro-ph/0407231 |s2cid=11468731}}</ref> The soft X-ray sub-coronal X-ray emission is much weaker than the hard X-ray coronal emission. The same behaviour has been measured in other F-class supergiants such as [[α Persei]] and is now believed to be a normal property of such stars.<ref name=ayres2018/>
== Evolution ==
The spectrum of Canopus indicates that it has exhausted its core hydrogen and [[stellar evolution|evolved]] away from the [[main sequence]], where it spent some 30 million years of its existence as a blue-white star <!-- source suggests B2V but may be too exact --> of around 10 solar masses.<ref>{{cite journal |last1=Peimbert |first1=M. |last2=Wallerstein | first2= G.| last3= Pilachowski | first3= C. A. |title=An upper limit for the deuterium abundance in Canopus |journal=Astronomy and Astrophysics |date=1981 |volume=104 |issue=1 |pages=72–74 | bibcode=1981A&A...104...72P}}</ref> The position of Canopus in the [[H–R diagram]] indicates that it is currently in the core-helium burning phase.<ref name=vlti/> It is an intermediate mass star that has left the [[red-giant branch]] before its core became [[degenerate matter|degenerate]] and is now in a [[blue loop]].<ref name=desouza>{{Cite journal | last1 = Domiciano De Souza | first1 = A. | last2 = Bendjoya | first2 = P. | last3 = Vakili | first3 = F. | last4 = Millour | first4 = F. | last5 = Petrov | first5 = R. G. | title = Diameter and photospheric structures of Canopus from AMBER/VLTI interferometry | doi = 10.1051/0004-6361:200810450 | journal = Astronomy and Astrophysics | volume = 489 | issue = 2 | pages = L5–L8 | year = 2008 |bibcode = 2008A&A...489L...5D | url = https://hal.archives-ouvertes.fr/hal-00316994/document | doi-access = free }}</ref> Models of stellar evolution in the blue loop phase show that the length of the blue loop is strongly affected by rotation and mixing effects inside the star. It is difficult to determine whether a star is currently evolving towards hotter temperature or returning to cooler temperatures, since the evolutionary tracks for stars with different masses overlap during the blue loops.<ref name=smiljanic2006>{{cite journal |bibcode=2006A&A...449..655S |title=CNO in evolved intermediate mass stars |last1=Smiljanic |first1=R. |last2=Barbuy |first2=B. |last3=De Medeiros |first3=J. R. |last4=Maeder |first4=A. |journal=Astronomy and Astrophysics |year=2006 |volume=449 |issue=2 |page=655 |doi=10.1051/0004-6361:20054377 |arxiv=astro-ph/0511329 |s2cid=3711409 }}</ref>
Canopus lies on the warm side of the [[instability strip]] and does not pulsate like [[Cepheid variables]] of a similar luminosity.<ref name=ayres2011>{{cite journal |doi=10.1088/0004-637X/738/2/120 |title=The Curious Case of the Alpha Persei Corona: A Dwarf in Supergiant's Clothing? |year=2011 |last1=Ayres |first1=Thomas R. |journal=The Astrophysical Journal |volume=738 |issue=2 |page=120 |bibcode=2011ApJ...738..120A |doi-access=free }}</ref> However its atmosphere does appear to be unstable, showing strong signs of convection.<ref name=smiljanic2006/>
Canopus may not be massive enough for its [[nuclear fusion|fusion]] chain to reach iron and trigger a core collapse and subsequent [[supernova]], instead eventually becoming a neon-oxygen [[white dwarf]].<ref name=Kalerstars/>
==Cultural significance ==
Canopus was known to the ancient Mesopotamians and given the name ''NUN-ki'' and represented the city of [[Eridu]] in the ''Three Stars Each'' [[Babylonian star catalogues]] and later [[MUL.APIN]] around 1100 BC.<ref>{{cite journal | last = Rogers | first = John H. | date = 1998 | title = Origins of the Ancient Constellations: I. The Mesopotamian Traditions | journal = Journal of the British Astronomical Association | volume = 108 | issue = 1 | pages = 9–28 | bibcode = 1998JBAA..108....9R}}</ref> Today, the star [[Sigma Sagittarii]] is known by the common name Nunki.<ref name=allen>{{citation | page=359 | first1=Richard Hinckley | last1=Allen | title=Star Names, their lore and meaning}}</ref>
Canopus was not visible to the mainland [[Ancient Greece|ancient Greeks]] and [[Roman Empire|Romans]]; it was, however, visible to the [[ancient Egypt]]ians.<ref name="Schaaf107">Schaaf, p. 107.</ref> Hence [[Aratus]] did not write of the star as it remained below the horizon, while [[Eratosthenes]] and [[Ptolemy]]—observing from [[Alexandria]]—did, calling it ''Kanōbos''.<ref name=ridpathCr>{{cite web| url=http://www.ianridpath.com/startales/carina.htm | title=Carina |last1=Ridpath|first1=Ian|publisher=self-published |work=Star Tales | access-date= 10 December 2015}}</ref> An [[Egypt]]ian priestly poet in the time of [[Thutmose III]] mentions the star as ''Karbana,'' "the star which pours his light in a glance of fire, when he disperses the morning dew."<ref name="hinkley63" /> Under the [[Ptolemies]], the star was known as ''Ptolemaion'' ([[Ancient Greek|Greek]]: Πτολεμαῖον) and its [[acronychal rising]] marked the date of the Ptolemaia festival, which was held every four years, from 262 to 145 BC.<ref>[[Martianus Capella]] 7.838, {{cite journal | last1 = Hazzard | last2 = Fitzgerald | year = 1991 | title = The Regulation of the Ptolemeia | journal = Journal of the Royal Astronomical Society of Canada | volume = 85 | pages = 6–23 |bibcode = 1991JRASC..85....6H }}; Hazzard. 2000. ''Imagination of a Monarchy: Studies in Ptolemaic Propaganda'', 34–36.</ref>
[[File:Statue of Averroes in Córdoba, Spain.jpg|thumb|upright|[[Averroes]], who used his 1153 observation of Canopus in [[Marrakesh]] while the star was invisible in his native Spain as an argument that the [[Spherical Earth|earth is round]].<ref name=ibn_rushd/>]]
===India===
In Indian [[Vedas|Vedic literature]], Canopus is associated with the sage [[Agastya]], one of the ancient [[siddhar]]s and [[rishi]]s (the others are associated with the stars of the [[Big Dipper]]).<ref name="Frawley 1993">{{cite book|last=Frawley|first=David|title=Gods, Sages and Kings: Vedic Secrets of Ancient Civilization|publisher=Motilal Banarsidass |location=New Delhi, India|date=1993}}</ref> To Agastya, the star is said to be the 'cleanser of waters', and its rising coincides with the calming of the waters of the [[Indian Ocean]]. It is thus considered the son of [[Pulastya]], son of [[Brahma]]. Canopus is described by [[Pliny the Elder]] and [[Gaius Julius Solinus]] as the largest, brightest and only source of [[starlight]] for navigators near [[Tamraparni]] island (ancient Sri Lanka) during many nights.<ref>{{cite book |last1=Pridham |first1=Charles |title=An Historical, Political, and Statistical Account of Ceylon and Its Dependencies |date=1849 |publisher=T. and W. Boone |page=7 |url=https://books.google.com/books?id=O4aqHOMSJdYC&pg=PR19-IA5|language=en}}</ref><ref name="Frawley 1993"/><ref>{{cite book |last1=Elder |first1=Pliny the |title=Delphi Complete Works of Pliny the Elder (Illustrated) |date=2015 |publisher=Delphi Classics |url=https://books.google.com/books?id=OrJ0CgAAQBAJ&pg=PA343|language=en}}</ref>
===China===
Canopus was described as Shou Xing, the Star of Longevity, in the ''Shiji'' ([[Records of the Grand Historian]]) completed in 94 BC by Chinese historian [[Sima Qian]].<ref name=fong83>{{cite journal | title=The Iconography of the Popular Gods of Happiness, Emolument, and Longevity (Fu Lu Shou) | first=Mary H. |last=Fong | journal=Artibus Asiae | volume= 44 | issue= 2/3 | year=1983| pages= 159–199 | doi= 10.2307/3249596| jstor=3249596 }}</ref> Drawing on sources from the [[Warring States period]], he noted it to be the southern counterpart of [[Sirius]],<ref name="IDP"/> and wrote of a sanctuary dedicated to it established by Emperor [[Qin Shi Huang]] between 221 and 210 BC. During the [[Han dynasty]], the star was auspicious, its appearance in the southern sky heralding peace and absence war.<ref name=fong83/> From the imperial capital [[Chang'an]], the star made a low transit across the southern sky, indicating true south to observers, and was often obscured by clouds.<ref name=baumann19>{{cite journal | title=The White Old Man: Géluk-Mongolian Canopus Allegory and the Existence of God | first=Brian | last=Baumann | journal= Central Asiatic Journal | volume= 62 | issue= 1 | year=2019| pages= 35–68 | doi=10.13173/centasiaj.62.1.0035| s2cid=213083544 }}</ref> During this time it was also equated with [[Old Man of the South Pole]] (in {{zh|c=南极老人|p=Nanji Lǎorén}})<ref name=fong83/> Under this name, Canopus appears (albeit misplaced northwards) on the medieval Chinese manuscript the [[Dunhuang Star Chart]], although it cannot be seen from the Chinese capital of [[Chang'an]].<ref name="IDP">{{cite journal|bibcode=2009JAHH...12...39B|arxiv=0906.3034|title=The Dunhuang Sky: A Comprehensive Study of the Oldest Known Star Atlas|volume=12|issue=1|pages=39–59|last1=Bonnet-Bidaud|first1=Jean-Marc |last2=Praderie|first2=Françoise |last3=Whitfield|first3=Susan |author-link=Susan Whitfield |journal=The International Dunhuang Project: The Silk Road Online|year=2009}}</ref> The Chinese astronomer [[Yi Xing]] had journeyed south to chart Canopus and other far southern stars in 724 AD.<ref>{{cite book|last=Needham|first=Joseph|title=Science and Civilisation in China: Volume 3, Mathematics and the Sciences of the Heavens and the Earth|publisher=Cambridge University Press|location=Cambridge, United Kingdom|date=1959|pages=274|isbn=0521058015}}</ref> Its personification as the Old Man Star was popularised in the [[Tang Dynasty]], where it appeared often in poetry and memorials. Later still, during the [[Ming Dynasty]], the star was established as one of the [[Sanxing (deities)|Three Stars]] (Fu Lo Shou), appearing frequently in art and literature of the time.<ref name=fong83/> This symbolism spread into neighbouring cultures in Asia.<ref name=baumann19/>
In Japan, Canopus is known as ''Mera-boshi'' and ''Roujin-sei'' (the old man star),<ref>{{cite conference |url=http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |title=Stellar Iconology and Astronomical Folklore in Japan |author=Takao Ibaraki |book-title=International Planetarium Society (IPS) Conferences 1996 |publisher=International Planetarium Society |location=Osaka |date=14 July 1996 |access-date=25 February 2012 |url-status=dead |archive-url=https://web.archive.org/web/20120326195757/http://www2.tba.t-com.ne.jp/october-country/ips96/japanese_star.html |archive-date=2012-03-26 }}</ref> and in Mongolia, it was personified as the White Old Man.<ref name=fong83/> Although the link was known in Tibet, with names such as ''Genpo karpo'' (''Rgan po dkar po'') or ''Genkar'' (''Rgan dkar'') "White Old Man", the symbolism was not popular. Instead, Canopus was more commonly named ''Karma Rishi སྐར་མ་རི་ཥི།'', derived from Indian mythology. Tibetans celebrated the star's heliacal rising with ritual bathing and associated it with morning dew.<ref name=baumann19/>
===Polynesia===
Bright stars were important to the ancient [[Polynesian culture|Polynesians]] for navigation between the many islands and atolls of the Pacific Ocean. Low on the horizon, they acted as stellar compasses to assist mariners in charting courses to particular destinations. Canopus served as the southern wingtip of a "Great Bird" constellation called ''Manu'', with Sirius as the body and [[Procyon]] the northern wingtip, which divided the Polynesian night sky into two hemispheres.<ref name="Holberg">{{cite book | last=Holberg | first=J.B. | title=Sirius: Brightest Diamond in the Night Sky | date=2007 | publisher=Praxis Publishing | location=Chichester, UK | isbn=978-0-387-48941-4 | pages=[https://archive.org/details/siriusbrightestd0000holb/page/25 25–26] | url=https://archive.org/details/siriusbrightestd0000holb/page/25 }}</ref> The [[Hawaiian people]] called Canopus ''Ke Alii-o-kona-i-ka-lewa'', "The chief of the southern expanse"; it was one of the stars used by [[Hawaiʻiloa]] and Ki when they traveled to the [[Southern Ocean]].{{sfn|Makemson|1941|p=198}} The [[Māori people]] of [[New Zealand|New Zealand/Aotearoa]] had several names for Canopus. ''[[Ariki]]'' ("High-born"), was known as a solitary star that appeared in the east, prompting people to weep and chant.{{sfn|Makemson|1941|p=201}} They also named it ''[[Atutahi]]'', ''Aotahi'' or ''Atuatahi'', "Stand Alone".<ref>p. 419, [https://books.google.com/books?id=p7dR2w1Wv2sC ''Mythology: Myths, Legends and Fantasies''], Janet Parker, Alice Mills, Julie Stanton, Durban, Struik Publishers, 2007.</ref> Its solitary nature indicates it is a ''[[Tapu (Polynesian culture)|tapu]]'' star, as ''tapu'' people are often solitary. Its appearance at the beginning of the ''Maruaroa'' season foretells the coming winter; light rays to the south indicate a cold wet winter, and to the north foretell a mild winter. Food was offered to the star on its appearance.<ref name="Best22">{{cite book|last=Best|first=Elsdon|title=Astronomical Knowledge of the Maori: Genuine and Empirical|publisher=Dominion Museum|location=Wellington, New Zealand|date=1922|pages=34–35|url=http://nzetc.victoria.ac.nz/tm/scholarly/tei-BesAstro-t1-body-d1-d6-d4.html}}</ref> This name has several mythologies attached to it. One story tells of how Atutahi was left outside the basket representing the [[Milky Way]] when [[Tāne]] wove it. Another related myth about the star says that Atutahi was the first-born child of [[Rangi and Papa|Rangi]], who refused to enter the Milky Way and so turned it sideways and rose before it. The same name is used for other stars and constellations throughout Polynesia.{{sfn|Makemson|1941|pp=200–202}} ''Kapae-poto'', "Short horizon", referred to it rarely setting as seen in New Zealand;{{sfn|Makemson|1941|p=217}} ''Kauanga'' ("Solitary") was the name for Canopus only when it was the last star visible before sunrise.{{sfn|Makemson|1941|p=218}} The people of the [[Society Islands]] had two names for Canopus, as did the [[Tuamotu]] people. The Society Islanders called Canopus ''Taurua-e-tupu-tai-nanu'', "Festivity-whence-comes-the-flux-of-the-sea", and ''Taurua-nui-o-te-hiti-apatoa'' "Great-festivity-of-the-border-of-the-south",{{sfn|Makemson|1941|p=259}} and the Tuamotu people called the star ''Te Tau-rari'' and ''Marere-te-tavahi'', the latter said to be the true name for the former, "He-who-stands-alone".{{sfn|Makemson|1941|p=229}}
===Africa===
In the [[Guanches|Guanche]] mythology of the island of [[Tenerife]] (Spain), the star Canopus was linked with the goddess [[Chaxiraxi]].<ref name="Rumeu">{{cite book|author=Antonio Rumeu de Armas|title=La conquista de Tenerife, 1494–1496|url=https://books.google.com/books?id=Ck4BAAAAMAAJ|year=1975|publisher=Aula de Cultura de Tenerife|isbn=9788450071078}}</ref>
The [[Tswana people]] of [[Botswana]] knew Canopus as ''Naka''. Appearing late in winter skies, it heralded increasing winds and a time when trees lose their leaves. Stock owners knew it was time to put their sheep with rams.<ref>{{cite journal|last=Clegg|first=Andrew|date=1986|title=Some Aspects of Tswana Cosmology|journal=Botswana Notes and Records|volume=18|pages=33–37|jstor=40979758 }}</ref> In southern Africa, the Sotho, Tswana and Venda people called Canopus ''Naka'' or ''Nanga'', “the Horn Star”, while the Zulu and Swazi called it ''inKhwenkwezi'' "Brilliant star". It appears in the predawn sky in the third week of May. According to the Venda, the first person to see Canopus would blow a ''phalaphala'' horn from the top of a hill, getting a cow for a reward. The Sotho chiefs also awarded a cow, and ordered their medicine men to roll bone dice and read the fortune for the coming year.<ref name=snedegar95>{{cite journal |last1=Snedegar |first1=K.V. |title=Stars and seasons in Southern Africa |journal=Vistas in Astronomy |date=1995 |volume=39 |issue=4 |pages=529–38 |doi=10.1016/0083-6656(95)00008-9|bibcode=1995VA.....39..529S }}</ref> To the [[ǀXam language|ǀXam]]-speaking [[Bushmen]] of South Africa, Canopus and Sirius signalled the appearance of termites and flying ants. They also believed that stars had the power to cause death and misfortune, and they would pray to [[Sirius]] and Canopus in particular to impart good fortune or skill.<ref>{{cite journal| title="The Sky's Things", <nowiki>|</nowiki>xam Bushman 'Astrological Mythology' as recorded in the Bleek and Lloyd Manuscripts |last1=Hollman|first1=J. C.|journal=African Sky|volume= 11|page=8 |bibcode=2007AfrSk..11....8H|year = 2007 }}</ref> The [[ǃKung people]] of the [[Kalahari Desert]] in Botswana held Canopus and Capella to be the horns of ''tshxum'' (the Pleiades), the appearance of all three marking the end of the dry season and start of the rainy season.<ref>{{cite journal |last1=Marshall |first1=Lorna |title=Two Ju/ wa constellations |journal=Botswana Notes & Records |date=1975 |volume=7 |issue=1 |pages=153–159 | issn=0525-5090 |url=https://journals.co.za/docserver/fulltext/botnotes/7/1/548.pdf?expires=1590793041&id=id&accname=guest&checksum=3204085F9555AD9D083799E1F38E3AED}}</ref>
===Americas===
The [[Navajo]] observed the star and named it ''Maʼii Bizòʼ'', the “Coyote Star”. According to legend, Maʼii (Coyote) took part in the naming and placing of the star constellations during
the creation of the universe. He placed Canopus directly south, naming it after himself.<ref name="Maryboy">Maryboy, Nancy D. (2004). ''A Guide to Navajo Astronomy.'' Indigenous Education Institute : Bluff, Utah.</ref>
The [[Kalapalo]] people of [[Mato Grosso]] state in Brazil saw Canopus and [[Procyon]] as ''Kofongo'' "Duck", with [[Castor (star)|Castor]] and [[Pollux (star)|Pollux]] representing his hands. The asterism's appearance signified the coming of the rainy season and increase in [[manioc]], a food staple fed to guests at feasts.<ref name="basso87">{{cite book|last=Basso|first=Ellen B. |title=In Favor of Deceit: A Study of Tricksters in an Amazonian Society|publisher=University of Arizona Press|location=Tucson, Arizona|date=1987|page=[https://archive.org/details/infavorofdeceits0000bass/page/360 360]|isbn=0816510229|url=https://archive.org/details/infavorofdeceits0000bass|url-access=registration}}</ref>
===Australia===
Canopus is identified as the moiety ancestor ''Waa'' "Crow" to some [[Koori]] people in southeastern Australia.<ref>{{cite book|last=Mudrooroo|title=Aboriginal mythology: an A-Z spanning the history of aboriginal mythology from the earliest legends to the present day|publisher=HarperCollins|location=London|date=1994|page=27|isbn=1-85538-306-3}}</ref> The Boorong people of northwestern Victoria recalled that ''War'' (Canopus) was the brother of ''Warepil'' (Sirius), and that he brought fire from the heavens and introduced it to humanity. His wife was ''Collowgullouric War'' ([[Eta Carinae]]).<ref name=hamacher10>{{cite journal|last1=Hamacher|first1=Duane W. |last2=Frew|first2=David J. |date=2010|title= An Aboriginal Australian Record of the Great Eruption of Eta Carinae|journal=Journal of Astronomical History & Heritage |volume=13|issue=3|pages= 220–34|bibcode=2010JAHH...13..220H|arxiv = 1010.4610 }}</ref> The Pirt-Kopan-noot people of western Victoria tell of ''Waa'' "Crow" falling in love with a queen, ''Gneeanggar'' "Wedge-tailed Eagle" (Sirius) and her six attendants (the Pleiades). His advances spurned, he hears that the women are foraging for grubs and so transforms himself into a grub. When the women dig him out, he changes into a giant and carries her off.<ref>Mudroodoo, p. 55.</ref>
The Kulin people know Canopus as ''Lo-an-tuka''.<ref name=hamacher10/> Objects in the sky are also associated with states of being for some tribes; the Wailwun of northern New South Wales know Canopus as ''Wumba'' "deaf", alongside Mars as ''Gumba'' "fat" and Venus as ''Ngindigindoer'' "you are laughing".<ref name="noctuary">{{cite book|last=Johnson|first=Diane|title=Night skies of aboriginal Australia: a noctuary|publisher=University of Sydney|location=Darlington, New South Wales|date=1998|page=[https://archive.org/details/nightskiesofabor0000john/page/84 84]|isbn=1-86451-356-X|url-access=registration|url=https://archive.org/details/nightskiesofabor0000john/page/84}}</ref> Tasmanian aboriginal lore holds that Canopus is ''Dromerdene'', the brother of ''Moinee''; the two fought and fell out of the sky, with ''Dromerdene'' falling into Louisa Bay in southwest Tasmania.<ref name="haynes2000">{{cite book|last=Haynes|first=Ros D.|title= Astronomy and the Dreaming: The Astronomy of the Aboriginal Australians. Astronomy Across Cultures: The History of Non-Western Astronomy|publisher=Kluwer Academic Publishers|date=2000|page=57|doi=10.1007/978-94-011-4179-6_3}}</ref>
===Legacy===
[[File:HMS Glory LOC ggbain.17135.jpg|thumb|right|[[Canopus-class battleship]] HMS Glory]]
Canopus appears on the [[flag of Brazil]], symbolising the state of [[Goiás]].<ref>{{cite web
|title=Astronomy of the Brazilian Flag
|url=https://flagspot.net/flags/br_astro.html
|publisher=FOTW Flags Of The World website
}}</ref>
Two U.S. Navy [[submarine tender]]s have been named after Canopus, the [[USS Canopus (AS-9)|first]] serving from 1922 to 1942 and the [[USS Canopus (AS-34)|second]] serving from 1965 to 1994.
The [[Royal Navy]] built nine [[Canopus-class ship of the line|Canopus-class ships of the line]] in the early 19th century, and six {{Sclass|Canopus|battleship|1}}s which entered services between 1899 and 1902.
There are at least two mountains named after the star: [[Mount Canopus]] in Antarctica; and Mount Canopus or Canopus Hill in [[Tasmania]], the location of the [[Canopus Hill Observatory|Canopus Hill astronomical observatory]].
{{clear}}
<references />
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
ce29d5314b77a1352c960250ee049531d7f4de06
383
382
2023-07-07T08:51:31Z
SpaceMan
2
Replaced content with " Canopus is a bright [[star]] located in the southern constellation of [[Carina]], and is the second brightest star in the night sky after [[Sirius]]. It is a yellowish-white [[supergiant star]] that is approximately 310 [[light-years]] away from [[Earth]] and has a visual magnitude of -0.72. Canopus is a massive star, with an estimated [[mass]] of about 8 to 9 times that of the [[Sun]], and a radius of about 71 times that of the Sun. It is also one of the most lumi..."
wikitext
text/x-wiki
Canopus is a bright [[star]] located in the southern constellation of [[Carina]], and is the second brightest star in the night sky after [[Sirius]]. It is a yellowish-white [[supergiant star]] that is approximately 310 [[light-years]] away from [[Earth]] and has a visual magnitude of -0.72.
Canopus is a massive star, with an estimated [[mass]] of about 8 to 9 times that of the [[Sun]], and a radius of about 71 times that of the Sun. It is also one of the most luminous stars in the [[Milky Way]] [[galaxy]], with a luminosity that is estimated to be about 14,000 times that of the Sun.
The star's high luminosity and relatively low surface temperature make it appear yellow-white in color. It is also known for its high rotational velocity, with a rotational speed of around 70 km/s at the equator. This high velocity causes the star to bulge at the equator, making it slightly oblate in shape.
Canopus is believed to be around 8 to 10 million years old and is nearing the end of its life cycle. It is expected to eventually explode as a [[supernova]], although this is not expected to occur for several million years.
Canopus has been an important navigational star for many cultures throughout history, as it is visible from many parts of the world and is one of the brightest stars in the night sky. It was used by ancient navigators to help guide their ships across the ocean, and is still used by some modern-day navigators and [[astronomers]] for similar purposes.
In addition to its navigational importance, Canopus has also been the subject of scientific study and observation. Its high luminosity and relatively close distance have made it a useful target for astronomers studying the properties and behavior of stars, and it has been observed by a number of different telescopes and instruments over the years.
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
703ca6cefbc7350bce156c0180a373af4a078ec7
385
383
2023-07-07T08:54:42Z
SpaceMan
2
wikitext
text/x-wiki
[[File:Https://static.miraheze.org/astrobasewiki/2/23/Canopus.jpeg|thumb|center|Canopus]]
Canopus is a bright [[star]] located in the southern constellation of [[Carina]], and is the second brightest star in the night sky after [[Sirius]]. It is a yellowish-white [[supergiant star]] that is approximately 310 [[light-years]] away from [[Earth]] and has a visual magnitude of -0.72.
Canopus is a massive star, with an estimated [[mass]] of about 8 to 9 times that of the [[Sun]], and a radius of about 71 times that of the Sun. It is also one of the most luminous stars in the [[Milky Way]] [[galaxy]], with a luminosity that is estimated to be about 14,000 times that of the Sun.
The star's high luminosity and relatively low surface temperature make it appear yellow-white in color. It is also known for its high rotational velocity, with a rotational speed of around 70 km/s at the equator. This high velocity causes the star to bulge at the equator, making it slightly oblate in shape.
Canopus is believed to be around 8 to 10 million years old and is nearing the end of its life cycle. It is expected to eventually explode as a [[supernova]], although this is not expected to occur for several million years.
Canopus has been an important navigational star for many cultures throughout history, as it is visible from many parts of the world and is one of the brightest stars in the night sky. It was used by ancient navigators to help guide their ships across the ocean, and is still used by some modern-day navigators and [[astronomers]] for similar purposes.
In addition to its navigational importance, Canopus has also been the subject of scientific study and observation. Its high luminosity and relatively close distance have made it a useful target for astronomers studying the properties and behavior of stars, and it has been observed by a number of different telescopes and instruments over the years.
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
75598205b6bd967082034daf9a5fc8d7d378213a
386
385
2023-07-07T08:55:33Z
SpaceMan
2
wikitext
text/x-wiki
[[File:https://static.miraheze.org/astrobasewiki/2/23/Canopus.jpeg|thumb|center|Canopus]]
Canopus is a bright [[star]] located in the southern constellation of [[Carina]], and is the second brightest star in the night sky after [[Sirius]]. It is a yellowish-white [[supergiant star]] that is approximately 310 [[light-years]] away from [[Earth]] and has a visual magnitude of -0.72.
Canopus is a massive star, with an estimated [[mass]] of about 8 to 9 times that of the [[Sun]], and a radius of about 71 times that of the Sun. It is also one of the most luminous stars in the [[Milky Way]] [[galaxy]], with a luminosity that is estimated to be about 14,000 times that of the Sun.
The star's high luminosity and relatively low surface temperature make it appear yellow-white in color. It is also known for its high rotational velocity, with a rotational speed of around 70 km/s at the equator. This high velocity causes the star to bulge at the equator, making it slightly oblate in shape.
Canopus is believed to be around 8 to 10 million years old and is nearing the end of its life cycle. It is expected to eventually explode as a [[supernova]], although this is not expected to occur for several million years.
Canopus has been an important navigational star for many cultures throughout history, as it is visible from many parts of the world and is one of the brightest stars in the night sky. It was used by ancient navigators to help guide their ships across the ocean, and is still used by some modern-day navigators and [[astronomers]] for similar purposes.
In addition to its navigational importance, Canopus has also been the subject of scientific study and observation. Its high luminosity and relatively close distance have made it a useful target for astronomers studying the properties and behavior of stars, and it has been observed by a number of different telescopes and instruments over the years.
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
9495232b3d8b3cb9399c94cf905f3341124ddb96
387
386
2023-07-07T08:58:07Z
SpaceMan
2
wikitext
text/x-wiki
[[File:Canopus.jpeg|thumb|center|Canopus]]
Canopus is a bright [[star]] located in the southern constellation of [[Carina]], and is the second brightest star in the night sky after [[Sirius]]. It is a yellowish-white [[supergiant star]] that is approximately 310 [[light-years]] away from [[Earth]] and has a visual magnitude of -0.72.
Canopus is a massive star, with an estimated [[mass]] of about 8 to 9 times that of the [[Sun]], and a radius of about 71 times that of the Sun. It is also one of the most luminous stars in the [[Milky Way]] [[galaxy]], with a luminosity that is estimated to be about 14,000 times that of the Sun.
The star's high luminosity and relatively low surface temperature make it appear yellow-white in color. It is also known for its high rotational velocity, with a rotational speed of around 70 km/s at the equator. This high velocity causes the star to bulge at the equator, making it slightly oblate in shape.
Canopus is believed to be around 8 to 10 million years old and is nearing the end of its life cycle. It is expected to eventually explode as a [[supernova]], although this is not expected to occur for several million years.
Canopus has been an important navigational star for many cultures throughout history, as it is visible from many parts of the world and is one of the brightest stars in the night sky. It was used by ancient navigators to help guide their ships across the ocean, and is still used by some modern-day navigators and [[astronomers]] for similar purposes.
In addition to its navigational importance, Canopus has also been the subject of scientific study and observation. Its high luminosity and relatively close distance have made it a useful target for astronomers studying the properties and behavior of stars, and it has been observed by a number of different telescopes and instruments over the years.
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
619b26c2328f4a75413af5054862e410f6d3a5a1
File:Canopus.jpeg
6
175
384
2023-07-07T08:53:22Z
SpaceMan
2
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Earth
0
176
388
2023-07-07T09:19:43Z
SpaceMan
2
Created page with "{{Short description|Third planet from the Sun}} | name = Earth | alt_names = Prithvi, Gaia , Terra , the world, the globe , Mother Earth"
wikitext
text/x-wiki
{{Short description|Third planet from the Sun}}
| name = Earth
| alt_names = Prithvi, Gaia , Terra , the world, the globe , Mother Earth
675aa6e01be6c14a2756643b3c0fc461d100f354
389
388
2023-07-07T10:30:48Z
SpaceMan
2
wikitext
text/x-wiki
Earth is the third [[planet]] from the [[Sun]] and the only place known in the [[universe]] where [[life]] has originated and found habitability. Earth is the only planet known to sustain liquid surface water, with ocean water extending over 70.8% of the planet, making it an ocean world. Most other water is retained in Earth's polar regions, with large sheets of ice covering ocean and land, dwarfing Earth's groundwater, lakes, rivers and atmospheric water. The other 29.2% of the Earth's surface is land, consisting of continents and islands, and is widely covered by vegetation. Below the planet's surface lies the crust, consisting of several slowly moving tectonic plates, which interact to produce mountain ranges, volcanoes, and earthquakes. Inside the Earth's crust is a liquid outer core that generates the [[magnetosphere]], deflecting most of the destructive [[solar winds]] and cosmic radiation.
Earth is rounded into an ellipsoid with a circumference of about 40,000 km. It is the densest planet in the Solar System. Of the four rocky planets, it is the largest and most massive. Earth is about eight light-minutes away from the Sun and orbits it, taking a year (about 365.25 days) to complete one revolution. The Earth rotates around its own axis in slightly less than a day (in about 23 hours and 56 minutes). The Earth's axis of rotation is tilted with respect to the perpendicular to its orbital plane around the [[Sun]], producing seasons. Earth is orbited by one permanent natural [[satellite]], the Moon, which orbits Earth at 384,400 km (1.28 light seconds) and is roughly a quarter as wide as Earth. Through tidal locking, the [[Moon]] always faces the Earth with the same side, which causes tides, stabilizes Earth's axis, and gradually slows its rotation.
Earth, like most other bodies in the Solar System, formed 4.5 billion years ago from gas in the early [[Solar System]].
667cc7d96af9036fb33a1310b1a6b3b8991dee99
Galaxy
0
177
390
2023-07-07T15:03:15Z
SpaceMan
2
Created page with "A galaxy is a massive collection of [[stars]], gas, dust, and other celestial objects bound together by [[gravity]]. Galaxies come in a variety of shapes, sizes, and colors, and can range from small, irregularly shaped dwarf galaxies to large, spiral-shaped galaxies containing billions of stars. The [[Milky Way]], the galaxy in which [[Earth]] is located, is estimated to contain around 100 billion [[stars]], as well as a supermassive [[black hole]] at its center. The Mi..."
wikitext
text/x-wiki
A galaxy is a massive collection of [[stars]], gas, dust, and other celestial objects bound together by [[gravity]]. Galaxies come in a variety of shapes, sizes, and colors, and can range from small, irregularly shaped dwarf galaxies to large, spiral-shaped galaxies containing billions of stars.
The [[Milky Way]], the galaxy in which [[Earth]] is located, is estimated to contain around 100 billion [[stars]], as well as a supermassive [[black hole]] at its center. The Milky Way is a spiral galaxy, with arms of gas, dust, and stars spiraling out from the central bulge.
Galaxies are classified into several different types based on their shapes. Spiral galaxies, like the Milky Way, have a central bulge and spiral arms that extend outwards. Elliptical galaxies, on the other hand, are shaped like ellipsoids and have no discernible structure. Irregular galaxies have no particular shape or structure and are often the result of gravitational interactions with other galaxies.
Galaxies are also classified based on their color, which is determined by the types of stars and other objects within them. Blue galaxies contain young, hot stars, while red galaxies contain older, cooler stars. Green galaxies are a mixture of both young and old stars.
Galaxies are thought to have formed shortly after the [[Big Bang]], when the [[universe]] was still in its infancy. Over time, galaxies have evolved and changed as stars are born and die, as well as through gravitational interactions with other galaxies.
Despite their enormous size, galaxies are still subject to the laws of physics and are affected by a range of phenomena, including black holes, [[supernova]], and [[dark matter]]. Scientists continue to study galaxies to better understand their origins, evolution, and the intricate web of interactions that governs their behavior.
The study of galaxies has also led to a number of important discoveries and advancements in our understanding of the universe. For example, the discovery of the [[cosmic microwave background radiation]], which is believed to be leftover radiation from the Big Bang, was a crucial piece of evidence in support of the Big Bang theory.
== Summary ==
In summary, galaxies are massive collections of stars, gas, dust, and other celestial objects that are bound together by gravity. They come in a variety of shapes, sizes, and colors, and have played a critical role in our understanding of the universe and its origins. As scientists continue to study galaxies, we can expect to gain even greater insight into the workings of the universe and our place within it.
5e7cae4e4abd8178059b6376838ef9cffb0ae0ce
391
390
2023-07-07T15:03:50Z
SpaceMan
2
Protected "[[Galaxy]]": Edit warring ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))
wikitext
text/x-wiki
A galaxy is a massive collection of [[stars]], gas, dust, and other celestial objects bound together by [[gravity]]. Galaxies come in a variety of shapes, sizes, and colors, and can range from small, irregularly shaped dwarf galaxies to large, spiral-shaped galaxies containing billions of stars.
The [[Milky Way]], the galaxy in which [[Earth]] is located, is estimated to contain around 100 billion [[stars]], as well as a supermassive [[black hole]] at its center. The Milky Way is a spiral galaxy, with arms of gas, dust, and stars spiraling out from the central bulge.
Galaxies are classified into several different types based on their shapes. Spiral galaxies, like the Milky Way, have a central bulge and spiral arms that extend outwards. Elliptical galaxies, on the other hand, are shaped like ellipsoids and have no discernible structure. Irregular galaxies have no particular shape or structure and are often the result of gravitational interactions with other galaxies.
Galaxies are also classified based on their color, which is determined by the types of stars and other objects within them. Blue galaxies contain young, hot stars, while red galaxies contain older, cooler stars. Green galaxies are a mixture of both young and old stars.
Galaxies are thought to have formed shortly after the [[Big Bang]], when the [[universe]] was still in its infancy. Over time, galaxies have evolved and changed as stars are born and die, as well as through gravitational interactions with other galaxies.
Despite their enormous size, galaxies are still subject to the laws of physics and are affected by a range of phenomena, including black holes, [[supernova]], and [[dark matter]]. Scientists continue to study galaxies to better understand their origins, evolution, and the intricate web of interactions that governs their behavior.
The study of galaxies has also led to a number of important discoveries and advancements in our understanding of the universe. For example, the discovery of the [[cosmic microwave background radiation]], which is believed to be leftover radiation from the Big Bang, was a crucial piece of evidence in support of the Big Bang theory.
== Summary ==
In summary, galaxies are massive collections of stars, gas, dust, and other celestial objects that are bound together by gravity. They come in a variety of shapes, sizes, and colors, and have played a critical role in our understanding of the universe and its origins. As scientists continue to study galaxies, we can expect to gain even greater insight into the workings of the universe and our place within it.
5e7cae4e4abd8178059b6376838ef9cffb0ae0ce
392
391
2023-07-07T15:10:35Z
SpaceMan
2
wikitext
text/x-wiki
[https://cdn.britannica.com/05/94905-004-1AFF8DFF/Whirlpool-Galaxy-NGC-5195-Sc.jpg?s=1500x700&q=85 Galaxy]
A galaxy is a massive collection of [[stars]], gas, dust, and other celestial objects bound together by [[gravity]]. Galaxies come in a variety of shapes, sizes, and colors, and can range from small, irregularly shaped dwarf galaxies to large, spiral-shaped galaxies containing billions of stars.
The [[Milky Way]], the galaxy in which [[Earth]] is located, is estimated to contain around 100 billion [[stars]], as well as a supermassive [[black hole]] at its center. The Milky Way is a spiral galaxy, with arms of gas, dust, and stars spiraling out from the central bulge.
Galaxies are classified into several different types based on their shapes. Spiral galaxies, like the Milky Way, have a central bulge and spiral arms that extend outwards. Elliptical galaxies, on the other hand, are shaped like ellipsoids and have no discernible structure. Irregular galaxies have no particular shape or structure and are often the result of gravitational interactions with other galaxies.
Galaxies are also classified based on their color, which is determined by the types of stars and other objects within them. Blue galaxies contain young, hot stars, while red galaxies contain older, cooler stars. Green galaxies are a mixture of both young and old stars.
Galaxies are thought to have formed shortly after the [[Big Bang]], when the [[universe]] was still in its infancy. Over time, galaxies have evolved and changed as stars are born and die, as well as through gravitational interactions with other galaxies.
Despite their enormous size, galaxies are still subject to the laws of physics and are affected by a range of phenomena, including black holes, [[supernova]], and [[dark matter]]. Scientists continue to study galaxies to better understand their origins, evolution, and the intricate web of interactions that governs their behavior.
The study of galaxies has also led to a number of important discoveries and advancements in our understanding of the universe. For example, the discovery of the [[cosmic microwave background radiation]], which is believed to be leftover radiation from the Big Bang, was a crucial piece of evidence in support of the Big Bang theory.
==Summary==
In summary, galaxies are massive collections of stars, gas, dust, and other celestial objects that are bound together by gravity. They come in a variety of shapes, sizes, and colors, and have played a critical role in our understanding of the universe and its origins. As scientists continue to study galaxies, we can expect to gain even greater insight into the workings of the universe and our place within it.
<ref>https://www.britannica.com/science/galaxy</ref>
<ref>https://en.m.wikipedia.org/wiki/Galaxy</ref>
<references />
[[Category:Astronomy]]
__FORCETOC__
__NOEDITSECTION__
__INDEX__
__NEWSECTIONLINK__
cd1f4710f55c912fab06337312c51b42ad52108b
394
392
2023-07-07T15:14:22Z
SpaceMan
2
wikitext
text/x-wiki
[[File:NGC 4414 (NASA-med).jpg|thumb|center|NGC 4414]]
A galaxy is a massive collection of [[stars]], gas, dust, and other celestial objects bound together by [[gravity]]. Galaxies come in a variety of shapes, sizes, and colors, and can range from small, irregularly shaped dwarf galaxies to large, spiral-shaped galaxies containing billions of stars.
The [[Milky Way]], the galaxy in which [[Earth]] is located, is estimated to contain around 100 billion [[stars]], as well as a supermassive [[black hole]] at its center. The Milky Way is a spiral galaxy, with arms of gas, dust, and stars spiraling out from the central bulge.
Galaxies are classified into several different types based on their shapes. Spiral galaxies, like the Milky Way, have a central bulge and spiral arms that extend outwards. Elliptical galaxies, on the other hand, are shaped like ellipsoids and have no discernible structure. Irregular galaxies have no particular shape or structure and are often the result of gravitational interactions with other galaxies.
Galaxies are also classified based on their color, which is determined by the types of stars and other objects within them. Blue galaxies contain young, hot stars, while red galaxies contain older, cooler stars. Green galaxies are a mixture of both young and old stars.
Galaxies are thought to have formed shortly after the [[Big Bang]], when the [[universe]] was still in its infancy. Over time, galaxies have evolved and changed as stars are born and die, as well as through gravitational interactions with other galaxies.
Despite their enormous size, galaxies are still subject to the laws of physics and are affected by a range of phenomena, including black holes, [[supernova]], and [[dark matter]]. Scientists continue to study galaxies to better understand their origins, evolution, and the intricate web of interactions that governs their behavior.
The study of galaxies has also led to a number of important discoveries and advancements in our understanding of the universe. For example, the discovery of the [[cosmic microwave background radiation]], which is believed to be leftover radiation from the Big Bang, was a crucial piece of evidence in support of the Big Bang theory.
==Summary==
In summary, galaxies are massive collections of stars, gas, dust, and other celestial objects that are bound together by gravity. They come in a variety of shapes, sizes, and colors, and have played a critical role in our understanding of the universe and its origins. As scientists continue to study galaxies, we can expect to gain even greater insight into the workings of the universe and our place within it.
<ref>https://www.britannica.com/science/galaxy</ref>
<ref>https://en.m.wikipedia.org/wiki/Galaxy</ref>
<references />
[[Category:Astronomy]]
__FORCETOC__
__NOEDITSECTION__
__INDEX__
__NEWSECTIONLINK__
4daa84342ae05205f847fcba53911badd41129e6
File:NGC4414.jpeg
6
178
393
2023-07-07T15:12:33Z
SpaceMan
2
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
VY Canis Major
0
31
395
70
2023-07-07T15:21:17Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
[[File:VY Canis Major.jpg|thumb|VY Canis Major]]
==Definition==
VY Canis Majoris or VY CMa is a red Hypergiant [[star]]. It is located in the constellation [[Canis Major]]. It is one of the largest and brightest red hypergiants observed so far. It has a diameter of 1800 solar radii. This star emits energy very quickly and therefore, only exists for a few million years. It is estimated to be 4900 light years away from Earth. This star shows periodic light changes that last for approximately 2200 days.
==The crimson star==
The first known recorded observation of VY Canis Majoris is in the star catalogue of Jérôme Lalande, who recorded it on 7th March, 1801. Since 1847, VY CMa has been known to be a crimson star. Originally, University of Minnesota Professor Roberta M. Humphreys approximated that the radius of VY CMa is 1800-2100 times that of the Sun. This would make it the largest known star based on its radius.
==Surface==
This star also illustrates the conceptual problem of defining the "surface" of very large stars. This is very important for multiple reasons, including determining its radius and thus its size. It is a hundred thousand times less dense than the atmosphere of Earth (air) at sea level. Its average density is 0.000005 to 0.000010 kg per m³. Additionally, the star is constantly losing mass at an astounding rate. The boundary of such a star is usually defined by its "[[Rosseland Radius]]", which is based on its opaqueness to light.
4418fb3b986edba3dcf05f3740e75035c9699370
MediaWiki:Citizen-footer-tagline
8
179
397
2023-07-07T17:57:49Z
SpaceMan
2
Created page with "This Is ASTROBASE created by SpaceMan."
wikitext
text/x-wiki
This Is ASTROBASE created by SpaceMan.
5d6989ec599e5f7d1020048182d29a2272c948b1
User:SpaceMan/sandbox
2
180
398
2023-07-09T09:25:14Z
SpaceMan
2
Created page with "{{Infobox | title = Sun }}"
wikitext
text/x-wiki
{{Infobox
| title = Sun
}}
5c49d5832a8ca4460f3b6b0090da8196a41cca02
File:Web 1689012928768 1689012934764.jpg
6
181
400
2023-07-12T19:01:46Z
SpaceMan
2
wikitext
text/x-wiki
Astronomy picture
1c770de604435d50768248a49185707664338fc0
Universe
0
182
401
2023-07-12T19:03:30Z
SpaceMan
2
the universe is a vast and complex system of galaxies, stars, planets, and other celestial bodies, estimated to be approximately 13.8 billion years old and spanning an estimated 93 billion light-years in diameter. It began with the Big Bang and is constantly expanding, with dark matter and dark energy making up the majority of its mass and energy. Through ongoing scientific research, we continue to gain a better understanding of the universe and its properties.
wikitext
text/x-wiki
[[File:Web 1689012928768 1689012934764.jpg|thumb|center]]
==Definition==
The universe is a vast and complex system of [[galaxies]], [[stars]], [[planets]], and other celestial bodies. It is estimated to be approximately 13.8 billion years old and spans an estimated 93 billion [[light-years]] in diameter.
The universe is believed to have begun with a massive explosion called the [[Big Bang]], which occurred approximately 13.8 billion years ago. At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time.
The universe is composed of various types of matter and energy, including [[dark matter]] and [[dark energy]], which are not directly observable but are believed to make up the majority of the universe's mass and energy. Ordinary matter, which includes atoms and molecules, makes up only a small fraction of the universe.
The observable universe contains an estimated 2 trillion galaxies, each containing billions of stars. The [[Milky Way]] galaxy, which contains our [[solar system]], is estimated to contain approximately 100 billion stars. The universe also contains various types of celestial bodies, including planets, moons, [[asteroid]], and [[comet]].
The universe is constantly expanding, and the rate of expansion is accelerating. This expansion is believed to be driven by dark energy, which is causing the universe to expand at an increasing rate over time.
The study of the universe is a complex and ongoing field of scientific research. Astronomers and cosmologists use various tools and techniques, including telescopes, satellites, and computer simulations, to study the universe and its properties. Through these efforts, scientists have gained a better understanding of the origins, structure, and evolution of the universe, and continue to make new discoveries and advances in our understanding of the cosmos.
==Summary==
In summary, the universe is a vast and complex system of galaxies, stars, planets, and other celestial bodies, estimated to be approximately 13.8 billion years old and spanning an estimated 93 billion light-years in diameter. It began with the Big Bang and is constantly expanding, with dark matter and dark energy making up the majority of its mass and energy. Through ongoing scientific research, we continue to gain a better understanding of the universe and its properties.
----
<ref>https://en.m.wikipedia.org/wiki/Universe</ref>
__FORCETOC__
137016315513e49cbadda37cabd5613da238b038
402
401
2023-07-12T19:05:59Z
SpaceMan
2
wikitext
text/x-wiki
[[File:Web 1689012928768 1689012934764.jpg|thumb|center]]
==Definition==
The universe is a vast and complex system of [[galaxies]], [[stars]], [[planets]], and other celestial bodies. It is estimated to be approximately 13.8 billion years old and spans an estimated 93 billion [[light-years]] in diameter.
The universe is believed to have begun with a massive explosion called the [[Big Bang]], which occurred approximately 13.8 billion years ago. At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time.
The universe is composed of various types of matter and energy, including [[dark matter]] and [[dark energy]], which are not directly observable but are believed to make up the majority of the universe's mass and energy. Ordinary matter, which includes atoms and molecules, makes up only a small fraction of the universe.
The observable universe contains an estimated 2 trillion galaxies, each containing billions of stars. The [[Milky Way]] galaxy, which contains our [[solar system]], is estimated to contain approximately 100 billion stars. The universe also contains various types of celestial bodies, including planets, moons, [[asteroid]], and [[comet]].
The universe is constantly expanding, and the rate of expansion is accelerating. This expansion is believed to be driven by dark energy, which is causing the universe to expand at an increasing rate over time.
The study of the universe is a complex and ongoing field of scientific research. Astronomers and cosmologists use various tools and techniques, including telescopes, satellites, and computer simulations, to study the universe and its properties. Through these efforts, scientists have gained a better understanding of the origins, structure, and evolution of the universe, and continue to make new discoveries and advances in our understanding of the cosmos.
==Summary==
In summary, the universe is a vast and complex system of galaxies, stars, planets, and other celestial bodies, estimated to be approximately 13.8 billion years old and spanning an estimated 93 billion light-years in diameter. It began with the Big Bang and is constantly expanding, with dark matter and dark energy making up the majority of its mass and energy. Through ongoing scientific research, we continue to gain a better understanding of the universe and its properties.
----
<ref>https://en.m.wikipedia.org/wiki/Universe</ref>
__FORCETOC__
__INDEX__
17dd9ea36e4bca996fee77f10b3884f72f52171b
Main Page
0
1
404
396
2023-07-13T07:08:47Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase}}
'''Welcome to {{SITENAME}}!'''<br>
Astronomy is study of everything outside Earth which includes Star , planets , nebulas , supernovas, etc . It uses mathematics, physics, and chemistry in order to explain their origin and evolution.
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Note : Wiki is in development'''
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
<!-- Disclaimer: AI generated text are also being used , so if you find any mistake kindly reach The administrator -->
[[File:Logospaceman.png|alt=Logo|thumb]]
[[Category:Main]]
__NOEDITSECTION__
__INDEX__
__FORCETOC__
__NEWSECTIONLINK__
{{DEFAULTSORT:home}}
cd6c380854ee7fff8e8527bd10be25b477e8f16a
408
404
2023-07-13T07:37:37Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase}}
'''Welcome to {{SITENAME}}!'''<br>
[[Astronomy]] is the scientific discipline that studies the celestial objects and phenomena beyond the [[Earth's]] atmosphere. It encompasses a wide range of topics, including the properties, behavior, and evolution of [[stars]], [[planets]], [[galaxies]], and the universe as a whole. Astronomers use a variety of tools to study the cosmos, including telescopes, satellites, and computer simulations. [[Astronomy]] has been practiced for thousands of years and has contributed significantly to our understanding of the [[universe]], including the discovery of [[exoplanets]], the nature of [[black holes]], and the [[Big Bang]] theory. Today, astronomy continues to be a fascinating and active area of research, with astronomers exploring new ways to unlock the mysteries of the [[cosmos]].
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
<!-- Disclaimer: AI generated text are also being used , so if you find any mistake kindly reach The administrator -->
[[File:Logospaceman.png|alt=Logo|thumb]]
[[Category:Main]]
__NOEDITSECTION__
__INDEX__
__FORCETOC__
__NEWSECTIONLINK__
{{DEFAULTSORT:home}}
d2115b616de9e1a282a24f938ce190cc1c04ad3b
411
408
2023-07-13T17:36:09Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astrobase}}
'''Welcome to {{SITENAME}}!'''<br>
[[Astronomy]] is the scientific discipline that studies the celestial objects and phenomena beyond the [[Earth's]] atmosphere. It encompasses a wide range of topics, including the properties, behavior, and evolution of [[stars]], [[planets]], [[galaxies]], and the universe as a whole. Astronomers use a variety of tools to study the cosmos, including telescopes, satellites, and computer simulations. [[Astronomy]] has been practiced for thousands of years and has contributed significantly to our understanding of the [[universe]], including the discovery of [[exoplanets]], the nature of [[black holes]], and the [[Big Bang]] theory. Today, astronomy continues to be a fascinating and active area of research, with astronomers exploring new ways to unlock the mysteries of the [[cosmos]].
'''{{SITENAME}}''' is a wiki dedicated to astronomy .
<br>
'''Quick List'''<br>
[[Special:AllPages ]]<br>
[[Special:ListUsers]]<br>
[[Special:WantedPages]]
'''Astronomy Database Portal'''<br>
[https://astrobase.miraheze.org/wiki/Astronomy_Database_portal Astronomy Database Portal]
<br>
'''''Note: Some page are also using AI Generated Content.'''''
[[Category:Main]]
__NOEDITSECTION__
__INDEX__
__FORCETOC__
__NEWSECTIONLINK__
d0c1d6f5e0498f6a6a09c7cd1219e21d76c70862
File:CMB Timeline.jpg
6
183
405
2023-07-13T07:20:52Z
SpaceMan
2
wikitext
text/x-wiki
Cmb timeline
4b42ef4495959f832257ff2254478fafd78f6849
Big Bang
0
184
406
2023-07-13T07:23:32Z
SpaceMan
2
Created page with "==Definition== The Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago. [[File:CMB Timeline.jpg|alt=CMB Timeline |center|frameless|CMB timeline ]] At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time. As it ex..."
wikitext
text/x-wiki
==Definition==
The Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
[[File:CMB Timeline.jpg|alt=CMB Timeline |center|frameless|CMB timeline ]]
At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time. As it expanded, it cooled, allowing subatomic particles to form, including [[protons]], [[neutrons]], and [[electrons]].
During the first few minutes after the Big Bang, a process called [[nucleosynthesis]] occurred, in which atomic nuclei were formed through the fusion of protons and neutrons. This process created the light elements hydrogen, helium, and lithium, which were later used to form the first [[stars]] and [[galaxy]].
Over time, the expanding universe continued to cool, allowing atoms to form and the universe to become transparent to light. This moment, known as the [[cosmic microwave background radiation]], occurred approximately 380,000 years after the Big Bang and is still detectable today.
The Big Bang theory is supported by a variety of evidence, including observations of the cosmic microwave background radiation, the abundance of light elements in the universe, and the large-scale structure of the universe.
While the Big Bang theory is the prevailing scientific explanation for the origin and evolution of the universe, it is not without its limitations and areas of debate. For example, the theory does not yet provide a complete explanation for the formation of galaxies and other large structures in the universe, or the nature of [[dark matter]] and [[dark energy]], which are believed to make up the majority of the universe's mass and [[energy]].
Despite these limitations, the Big Bang theory remains a cornerstone of modern cosmology, providing a framework for understanding the history and evolution of the universe.
==What are some current areas of research related to the Big Bang theory?==
There are several current areas of research related to the Big Bang theory, which continue to expand our understanding of the origins and evolution of the universe. Some of these areas include:
1. Inflationary cosmology: Inflationary cosmology is a theory that suggests that the universe underwent a brief period of exponential expansion in the moments following the Big Bang. This theory helps to explain certain features of the cosmic microwave background radiation, such as its uniformity and lack of large-scale structure.
2. Dark matter and dark energy: Dark matter and dark energy are believed to make up the majority of the universe's mass and energy, but their exact nature is still not well understood. Researchers are continuing to study the properties of dark matter and dark energy, in order to better understand their role in the evolution of the universe.
3. Cosmic microwave background radiation: The cosmic microwave background radiation is the afterglow of the Big Bang, and provides a wealth of information about the early universe. Researchers are studying the cosmic microwave background radiation in order to learn more about the conditions that existed in the universe shortly after the Big Bang.
4. Large-scale structure of the universe: The large-scale structure of the universe, including the distribution of galaxies and other cosmic structures, provides important clues about the evolution of the universe. Researchers are using large-scale surveys and computer simulations to study the structure of the universe and its origins.
5. Neutrino physics: Neutrinos are subatomic particles that are produced in the early universe, and can provide important information about the conditions that existed shortly after the Big Bang. Researchers are studying the properties of neutrinos in order to better understand the early universe and its evolution.
Overall, these areas of research and others related to the Big Bang theory are helping to expand our understanding of the universe and its origins, and may lead toThe Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
53ad2aa0e7755cfcacd49e66dfdcc7fac38ee4b8
407
406
2023-07-13T07:33:15Z
SpaceMan
2
wikitext
text/x-wiki
==Definition==
The Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
[[File:CMB Timeline.jpg|alt=CMB Timeline |center|frameless|CMB timeline ]]
At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time. As it expanded, it cooled, allowing subatomic particles to form, including [[protons]], [[neutrons]], and [[electrons]].
During the first few minutes after the Big Bang, a process called [[nucleosynthesis]] occurred, in which atomic nuclei were formed through the fusion of protons and neutrons. This process created the light elements hydrogen, helium, and lithium, which were later used to form the first [[stars]] and [[galaxy]].
Over time, the expanding universe continued to cool, allowing atoms to form and the universe to become transparent to light. This moment, known as the [[cosmic microwave background radiation]], occurred approximately 380,000 years after the Big Bang and is still detectable today.
The Big Bang theory is supported by a variety of evidence, including observations of the cosmic microwave background radiation, the abundance of light elements in the universe, and the large-scale structure of the universe.
While the Big Bang theory is the prevailing scientific explanation for the origin and evolution of the universe, it is not without its limitations and areas of debate. For example, the theory does not yet provide a complete explanation for the formation of galaxies and other large structures in the universe, or the nature of [[dark matter]] and [[dark energy]], which are believed to make up the majority of the universe's mass and [[energy]].
Despite these limitations, the Big Bang theory remains a cornerstone of modern cosmology, providing a framework for understanding the history and evolution of the universe.
==What are some current areas of research related to the Big Bang theory?==
There are several current areas of research related to the Big Bang theory, which continue to expand our understanding of the origins and evolution of the universe. Some of these areas include:
1. Inflationary cosmology: Inflationary cosmology is a theory that suggests that the universe underwent a brief period of exponential expansion in the moments following the Big Bang. This theory helps to explain certain features of the cosmic microwave background radiation, such as its uniformity and lack of large-scale structure.
2. Dark matter and dark energy: Dark matter and dark energy are believed to make up the majority of the universe's mass and energy, but their exact nature is still not well understood. Researchers are continuing to study the properties of dark matter and dark energy, in order to better understand their role in the evolution of the universe.
3. Cosmic microwave background radiation: The cosmic microwave background radiation is the afterglow of the Big Bang, and provides a wealth of information about the early universe. Researchers are studying the cosmic microwave background radiation in order to learn more about the conditions that existed in the universe shortly after the Big Bang.
4. Large-scale structure of the universe: The large-scale structure of the universe, including the distribution of galaxies and other cosmic structures, provides important clues about the evolution of the universe. Researchers are using large-scale surveys and computer simulations to study the structure of the universe and its origins.
5. Neutrino physics: Neutrinos are subatomic particles that are produced in the early universe, and can provide important information about the conditions that existed shortly after the Big Bang. Researchers are studying the properties of neutrinos in order to better understand the early universe and its evolution.
Overall, these areas of research and others related to the Big Bang theory are helping to expand our understanding of the universe and its origins, and may lead toThe Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
[[Category:Astronomy]]
{{DEFAULTSORT:BigBang}}
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
c32ce964aa998a5991dd7ab454052672649e5275
425
407
2023-07-13T18:24:24Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
The Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
[[File:CMB Timeline.jpg|alt=CMB Timeline |center|frameless|CMB timeline ]]
At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time. As it expanded, it cooled, allowing subatomic particles to form, including [[protons]], [[neutrons]], and [[electrons]].
During the first few minutes after the Big Bang, a process called [[nucleosynthesis]] occurred, in which atomic nuclei were formed through the fusion of protons and neutrons. This process created the light elements hydrogen, helium, and lithium, which were later used to form the first [[stars]] and [[galaxy]].
Over time, the expanding universe continued to cool, allowing atoms to form and the universe to become transparent to light. This moment, known as the [[cosmic microwave background radiation]], occurred approximately 380,000 years after the Big Bang and is still detectable today.
The Big Bang theory is supported by a variety of evidence, including observations of the cosmic microwave background radiation, the abundance of light elements in the universe, and the large-scale structure of the universe.
While the Big Bang theory is the prevailing scientific explanation for the origin and evolution of the universe, it is not without its limitations and areas of debate. For example, the theory does not yet provide a complete explanation for the formation of galaxies and other large structures in the universe, or the nature of [[dark matter]] and [[dark energy]], which are believed to make up the majority of the universe's mass and [[energy]].
Despite these limitations, the Big Bang theory remains a cornerstone of modern cosmology, providing a framework for understanding the history and evolution of the universe.
==What are some current areas of research related to the Big Bang theory?==
There are several current areas of research related to the Big Bang theory, which continue to expand our understanding of the origins and evolution of the universe. Some of these areas include:
1. Inflationary cosmology: Inflationary cosmology is a theory that suggests that the universe underwent a brief period of exponential expansion in the moments following the Big Bang. This theory helps to explain certain features of the cosmic microwave background radiation, such as its uniformity and lack of large-scale structure.
2. Dark matter and dark energy: Dark matter and dark energy are believed to make up the majority of the universe's mass and energy, but their exact nature is still not well understood. Researchers are continuing to study the properties of dark matter and dark energy, in order to better understand their role in the evolution of the universe.
3. Cosmic microwave background radiation: The cosmic microwave background radiation is the afterglow of the Big Bang, and provides a wealth of information about the early universe. Researchers are studying the cosmic microwave background radiation in order to learn more about the conditions that existed in the universe shortly after the Big Bang.
4. Large-scale structure of the universe: The large-scale structure of the universe, including the distribution of galaxies and other cosmic structures, provides important clues about the evolution of the universe. Researchers are using large-scale surveys and computer simulations to study the structure of the universe and its origins.
5. Neutrino physics: Neutrinos are subatomic particles that are produced in the early universe, and can provide important information about the conditions that existed shortly after the Big Bang. Researchers are studying the properties of neutrinos in order to better understand the early universe and its evolution.
Overall, these areas of research and others related to the Big Bang theory are helping to expand our understanding of the universe and its origins, and may lead toThe Big Bang theory is the prevailing scientific explanation for the origin and evolution of the [[universe]]. According to this theory, the universe began as a [[singularity]], a point of infinite density and temperature, approximately 13.8 billion years ago.
[[Category:Astronomy]]
{{DEFAULTSORT:BigBang}}
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
5713f1a8b30f22a4f9347a14dfc4d61d44440b58
Earth's
0
185
409
2023-07-13T08:26:10Z
SpaceMan
2
Redirected page to [[Earth]]
wikitext
text/x-wiki
#REDIRECT [[Earth]]
__STATICREDIRECT__
45c3bc0208c3e61fe74305e509c5e572012de22b
Galaxies
0
186
410
2023-07-13T08:27:31Z
SpaceMan
2
Redirected page to [[Galaxy]]
wikitext
text/x-wiki
#REDIRECT [[Galaxy ]]
ee01d9683043e673e7758285f093d85f76b8a5e2
Astronomy Database portal
0
30
412
88
2023-07-13T17:37:10Z
SpaceMan
2
/* Astronomy Data Portal */
wikitext
text/x-wiki
This is Astronomy Data Portal (ADP).
Note: following content may be taken from verious sources.
==Star==
{| class="wikitable"
|+STAR
|-
|[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
|-
|[https://astrobase.miraheze.org/wiki/Sirius Sirius]
|-
|[https://astrobase.miraheze.org/wiki/Canopus Canopus]
|}
cbce893de517dde6ba48f408a4b4371388cb135e
413
412
2023-07-13T17:39:23Z
SpaceMan
2
/* Star */
wikitext
text/x-wiki
This is Astronomy Data Portal (ADP).
Note: following content may be taken from verious sources.
==Star==
{| class="wikitable"
|+STAR
|-
|[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
|-
|[https://astrobase.miraheze.org/wiki/Sirius Sirius]
|-
|[https://astrobase.miraheze.org/wiki/Canopus Canopus]
|-
|
[https://astrobase.miraheze.org/wiki/Sun Sun]
|}
0c004b7ac02e1eb4d43995898bc02935916dba58
414
413
2023-07-13T17:40:44Z
SpaceMan
2
wikitext
text/x-wiki
{{DISPLAYTITLE:Astronomy Data portal}}
This is Astronomy Data Portal (ADP).
Note: following content may be taken from verious sources.
==Star==
{| class="wikitable"
|+STAR
|-
|[https://astrobase.miraheze.org/wiki/VY_Canis_Major VY Canis Major]
|-
|[https://astrobase.miraheze.org/wiki/Sirius Sirius]
|-
|[https://astrobase.miraheze.org/wiki/Canopus Canopus]
|-
|
[https://astrobase.miraheze.org/wiki/Sun Sun]
|}
[[Category:Main]]
[[Category:Astronomy]]
{{DEFAULTSORT:Astronomy_Data_portal}}
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
c0fc8918e99f8ca7954333f9211a831a61026522
Cosmos
0
187
415
2023-07-13T17:42:44Z
SpaceMan
2
Redirected page to [[Universe]]
wikitext
text/x-wiki
#REDIRECT [[Universe ]]
__INDEX__
__NEWSECTIONLINK__
c65372757cd62073377bedc18a9cdd6d27294a66
Universe
0
182
416
402
2023-07-13T17:43:19Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
[[File:Web 1689012928768 1689012934764.jpg|thumb|center]]
The universe is a vast and complex system of [[galaxies]], [[stars]], [[planets]], and other celestial bodies. It is estimated to be approximately 13.8 billion years old and spans an estimated 93 billion [[light-years]] in diameter.
The universe is believed to have begun with a massive explosion called the [[Big Bang]], which occurred approximately 13.8 billion years ago. At the time of the Big Bang, the universe was extremely hot and dense, and rapidly expanded and cooled over time.
The universe is composed of various types of matter and energy, including [[dark matter]] and [[dark energy]], which are not directly observable but are believed to make up the majority of the universe's mass and energy. Ordinary matter, which includes atoms and molecules, makes up only a small fraction of the universe.
The observable universe contains an estimated 2 trillion galaxies, each containing billions of stars. The [[Milky Way]] galaxy, which contains our [[solar system]], is estimated to contain approximately 100 billion stars. The universe also contains various types of celestial bodies, including planets, moons, [[asteroid]], and [[comet]].
The universe is constantly expanding, and the rate of expansion is accelerating. This expansion is believed to be driven by dark energy, which is causing the universe to expand at an increasing rate over time.
The study of the universe is a complex and ongoing field of scientific research. Astronomers and cosmologists use various tools and techniques, including telescopes, satellites, and computer simulations, to study the universe and its properties. Through these efforts, scientists have gained a better understanding of the origins, structure, and evolution of the universe, and continue to make new discoveries and advances in our understanding of the cosmos.
==Summary==
In summary, the universe is a vast and complex system of galaxies, stars, planets, and other celestial bodies, estimated to be approximately 13.8 billion years old and spanning an estimated 93 billion light-years in diameter. It began with the Big Bang and is constantly expanding, with dark matter and dark energy making up the majority of its mass and energy. Through ongoing scientific research, we continue to gain a better understanding of the universe and its properties.
----
<ref>https://en.m.wikipedia.org/wiki/Universe</ref>
__FORCETOC__
__INDEX__
3e9d8b66b758f9d7679f0ea4243f4b2b1d196a2f
Acceleration
0
12
417
22
2023-07-13T17:43:59Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
It is defined as the change in the velocity of an object per unit time.
If the velocity of an object changes frIt is defined as the change in the om an initial value u to final value v in time t, then acceleration a is given by
Acceleration = (final velocity - initial velocity )/ Time
==Properties==
SI unit of acceleration is m/s²
It is a [[Vector quantity]], its direction is in the direction of change in velocity.
It may be positive, negative or zero.
If an object is moving with constant or uniform [[velocity]], then its acceleration is zero.
==Uniform acceleration==
A body is said to have uniform acceleration, if it travels in a straight line and its velocity increases or decreases by equal [[magnitude]] in equal intervals of time. For example :
(ii) The [[motion]] of a bicycle going down the slope of a road (when the rider is not pedaling and [[air resistance]] is negligible).
==Non-Uniform acceleration==
A body is said to have non-uniform acceleration, if its velocity changes by unequal magnitude in equal intervals of time.
For example - The motion of a car on a crowded road.
==Retardation or deceleration==
A body is said to be retarded if the magnitude of its velocity decreases with time. In this case, the final velocity of the moving body is less than the initial velocity i.e., v<u.
For example - When a person applies brake on a moving car, its velocity decreases with time. For example, if acceleration is a = - 5 m/s ^ 2 we can write this as the deceleration or retardation is taking place at 5 m/s² or you can also put it as acceleration in the opposite direction at the rate of 5 m/s².
3fbca5aaf469c2008f7d8246b5672bcbe8e9aea8
Active Galactic Nucleus
0
167
418
361
2023-07-13T17:48:00Z
SpaceMan
2
/* Definition */
wikitext
text/x-wiki
An active galactic nucleus (AGN) is a region at the center of a [[galaxy]] that emits a significant amount of [[radiation]] and displays strong variability in its emission properties. This phenomenon is thought to be caused by the accretion of material onto a supermassive [[black hole]] located at the center of the galaxy.
As material falls into the black hole, it heats up and emits radiation across the [[electromagnetic spectrum]], from [[radio waves]] to [[gamma-rays]]. This process generates a significant amount of [[energy]], making AGNs some of the most luminous objects in the [[universe]].
AGNs can exhibit a variety of emission features, including broad emission lines, X-ray emission, and strong radio emission. The properties of the emission lines can be used to classify AGNs into different types, such as [[Seyfert galaxies]], [[quasars]], and [[blazars]].
The study of AGNs is an active area of research, with astronomers using a variety of techniques to understand the physical processes that drive their emission. This includes studying the variability of AGNs on various timescales, measuring the properties of the accretion disks and jets that surround the black hole, and investigating the interaction between the black hole and the surrounding gas and stars in the galaxy.
AGNs are also important probes of the evolution of galaxies and the growth of supermassive black holes. Understanding the properties and behavior of AGNs is therefore crucial to our understanding of the formation and evolution of the universe as a whole.
802f5aef310eb7884d6ccb05cfca931d3dd0b65b
419
418
2023-07-13T17:51:06Z
SpaceMan
2
wikitext
text/x-wiki
An active galactic nucleus (AGN) is a region at the center of a [[galaxy]] that emits a significant amount of [[radiation]] and displays strong variability in its emission properties. This phenomenon is thought to be caused by the accretion of material onto a supermassive [[black hole]] located at the center of the galaxy.
As material falls into the black hole, it heats up and emits radiation across the [[electromagnetic spectrum]], from [[radio waves]] to [[gamma-rays]]. This process generates a significant amount of [[energy]], making AGNs some of the most luminous objects in the [[universe]].
AGNs can exhibit a variety of emission features, including broad emission lines, X-ray emission, and strong radio emission. The properties of the emission lines can be used to classify AGNs into different types, such as [[Seyfert galaxies]], [[quasars]], and [[blazars]].
The study of AGNs is an active area of research, with astronomers using a variety of techniques to understand the physical processes that drive their emission. This includes studying the variability of AGNs on various timescales, measuring the properties of the accretion disks and jets that surround the black hole, and investigating the interaction between the black hole and the surrounding gas and stars in the galaxy.
AGNs are also important probes of the evolution of galaxies and the growth of supermassive black holes. Understanding the properties and behavior of AGNs is therefore crucial to our understanding of the formation and evolution of the universe as a whole.
==Technique used to study AGN==
Astronomers use a variety of techniques to study active galactic nuclei (AGNs). Here are some of the techniques:
1. Spectroscopy: [[Astronomers]] use spectroscopy to study the emission lines in AGNs. Spectroscopy involves breaking down the light emitted by an AGN into its component wavelengths, revealing information about the elements and physical conditions in the emitting gas. This technique can be used to study the velocity of gas in the accretion disk and measure the mass of the central [[black hole]].
2. X-ray and Gamma-ray Astronomy: AGNs emit copious amounts of X-rays and gamma rays, which can be detected by [[telescopes]] that are sensitive to these high-energy wavelengths. These observations can provide information about the geometry and physical processes that occur in the [[accretion disk]] and jets around the [[black hole]].
3. Radio Astronomy: AGNs also emit strong [[radio waves]], which can be detected by radio telescopes. These observations can reveal the structure and properties of the jets that are launched from the AGN, as well as the magnetic fields and other physical conditions in the surrounding gas.
4. Time-domain Astronomy: Astronomers study the variability of AGNs on various timescales, from hours to years. This can provide information about the physical processes that occur near the black hole, such as changes in the accretion rate or the launching of a new jet.
5. Multi-wavelength Astronomy: AGNs emit radiation across the [[electromagnetic spectrum]], from radio waves to [[gamma rays]]. Studying AGNs at multiple wavelengths can provide a more complete picture of their properties and behavior.
414eae25f59d634022fc174b7115fd9d85635d87
421
419
2023-07-13T18:03:50Z
SpaceMan
2
wikitext
text/x-wiki
An active galactic nucleus (AGN) is a region at the center of a [[galaxy]] that emits a significant amount of [[radiation]] and displays strong variability in its emission properties. This phenomenon is thought to be caused by the accretion of material onto a supermassive [[black hole]] located at the center of the galaxy.
[[File:Active Galactic nucleus .jpg|alt=Active Galactic nucleus |center|frameless|Credit: C.M. Urry & P. Padovani.]]
As material falls into the black hole, it heats up and emits radiation across the [[electromagnetic spectrum]], from [[radio waves]] to [[gamma-rays]]. This process generates a significant amount of [[energy]], making AGNs some of the most luminous objects in the [[universe]].
AGNs can exhibit a variety of emission features, including broad emission lines, X-ray emission, and strong radio emission. The properties of the emission lines can be used to classify AGNs into different types, such as [[Seyfert galaxies]], [[quasars]], and [[blazars]].
The study of AGNs is an active area of research, with astronomers using a variety of techniques to understand the physical processes that drive their emission. This includes studying the variability of AGNs on various timescales, measuring the properties of the accretion disks and jets that surround the black hole, and investigating the interaction between the black hole and the surrounding gas and stars in the galaxy.
AGNs are also important probes of the evolution of galaxies and the growth of supermassive black holes. Understanding the properties and behavior of AGNs is therefore crucial to our understanding of the formation and evolution of the universe as a whole.
==Technique used to study AGN==
Astronomers use a variety of techniques to study active galactic nuclei (AGNs). Here are some of the techniques:
1. Spectroscopy: [[Astronomers]] use spectroscopy to study the emission lines in AGNs. Spectroscopy involves breaking down the light emitted by an AGN into its component wavelengths, revealing information about the elements and physical conditions in the emitting gas. This technique can be used to study the velocity of gas in the accretion disk and measure the mass of the central [[black hole]].
2. X-ray and Gamma-ray Astronomy: AGNs emit copious amounts of X-rays and gamma rays, which can be detected by [[telescopes]] that are sensitive to these high-energy wavelengths. These observations can provide information about the geometry and physical processes that occur in the [[accretion disk]] and jets around the [[black hole]].
3. Radio Astronomy: AGNs also emit strong [[radio waves]], which can be detected by radio telescopes. These observations can reveal the structure and properties of the jets that are launched from the AGN, as well as the magnetic fields and other physical conditions in the surrounding gas.
4. Time-domain Astronomy: Astronomers study the variability of AGNs on various timescales, from hours to years. This can provide information about the physical processes that occur near the black hole, such as changes in the accretion rate or the launching of a new jet.
5. Multi-wavelength Astronomy: AGNs emit radiation across the [[electromagnetic spectrum]], from radio waves to [[gamma rays]]. Studying AGNs at multiple wavelengths can provide a more complete picture of their properties and behavior.
77851a672d20b3298cf9756c2607dfe68b87cadd
File:Active Galactic nucleus .jpg
6
188
420
2023-07-13T18:03:14Z
SpaceMan
2
wikitext
text/x-wiki
Credit: C.M. Urry & P. Padovani.
352301842e5e005b54ecf932286dc16abf291772
Dark matter
0
189
422
2023-07-13T18:11:16Z
SpaceMan
2
Created page with "Dark matter is a hypothetical form of matter that is thought to make up a significant portion of the total matter content in the [[universe]]. It does not interact with light or other forms of [[electromagnetic radiation]], making it invisible to [[telescopes]] and other instruments that detect light. The existence of dark matter is inferred through its gravitational effects on visible matter, such as [[stars]] and [[galaxies]]. Observations of the velocities of galaxi..."
wikitext
text/x-wiki
Dark matter is a hypothetical form of matter that is thought to make up a significant portion of the total matter content in the [[universe]]. It does not interact with light or other forms of [[electromagnetic radiation]], making it invisible to [[telescopes]] and other instruments that detect light.
The existence of dark matter is inferred through its gravitational effects on visible matter, such as [[stars]] and [[galaxies]]. Observations of the velocities of galaxies and galaxy clusters suggest that there is more mass in these systems than can be accounted for by visible matter alone. This discrepancy is attributed to the presence of dark matter.
The nature of dark matter is still unknown, but it is believed to be composed of unknown particles that do not interact with light or other forms of electromagnetic radiation. These particles are thought to be electrically neutral and have very little interaction with other matter, making them difficult to detect.
Several experiments have been carried out to search for dark matter particles, including experiments that use underground detectors, [[particle accelerators]], and telescopes. However, no direct detection of dark matter has been made so far.
Despite its invisible nature, dark matter plays a crucial role in the structure and evolution of the universe. It is thought to have played a key role in the formation of large-scale structures, such as galaxies and [[galaxy clusters]], and its influence can be seen in the [[cosmic microwave background radiation]], the afterglow of the [[Big Bang]].
The study of dark matter is an active area of research in [[astrophysics]] and particle physics, with scientists working to better understand its properties and role in the [[universe]].
==Additional Details==
1. Dark matter is estimated to make up approximately 85% of the total matter content in the [[universe]]. The remaining 15% is made up of visible matter, such as stars, [[planets]], and gas.
2. Dark matter is believed to be distributed throughout the universe in a "halo" around galaxies and other cosmic structures. It is thought to be most dense in the centers of galaxies and less dense in the outer regions.
3. The properties of dark matter particles are still unknown, but several candidates have been proposed, including [[Weakly Interacting Massive Particles (WIMPs)]], [[Axions]], and [[Sterile Neutrinos]].
4. The effects of dark matter can be observed through its gravitational lensing of light from distant galaxies and its influence on the rotation curves of galaxies.
5. Dark matter is distinct from [[dark energy]], which is a hypothetical form of energy that is believed to be responsible for the acceleration of the expansion of the universe. Dark energy is thought to make up approximately 70% of the total [[energy]] content of the universe.
6. The study of dark matter is important for understanding the large-scale structure of the universe, the formation and evolution of galaxies, and the fundamental nature of matter and the universe as a whole.
Despite decades of research, the nature of dark matter remains one of the biggest mysteries in astrophysics. Scientists continue to search for new ways to detect dark matter particles and better understand their properties and role in the universe.
8cfe537ef0e4dc74e46a51a4f68501353d848f15
424
422
2023-07-13T18:16:34Z
SpaceMan
2
wikitext
text/x-wiki
Dark matter is a hypothetical form of matter that is thought to make up a significant portion of the total matter content in the [[universe]]. It does not interact with light or other forms of [[electromagnetic radiation]], making it invisible to [[telescopes]] and other instruments that detect light.
[[File:Dark-matter.jpg|alt=Dark Matter |center|frameless|Image via RAS/ S. Epps & M. Hudson / University of Waterloo.]]
The existence of dark matter is inferred through its gravitational effects on visible matter, such as [[stars]] and [[galaxies]]. Observations of the velocities of galaxies and galaxy clusters suggest that there is more mass in these systems than can be accounted for by visible matter alone. This discrepancy is attributed to the presence of dark matter.
The nature of dark matter is still unknown, but it is believed to be composed of unknown particles that do not interact with light or other forms of electromagnetic radiation. These particles are thought to be electrically neutral and have very little interaction with other matter, making them difficult to detect.
Several experiments have been carried out to search for dark matter particles, including experiments that use underground detectors, [[particle accelerators]], and telescopes. However, no direct detection of dark matter has been made so far.
Despite its invisible nature, dark matter plays a crucial role in the structure and evolution of the universe. It is thought to have played a key role in the formation of large-scale structures, such as galaxies and [[galaxy clusters]], and its influence can be seen in the [[cosmic microwave background radiation]], the afterglow of the [[Big Bang]].
The study of dark matter is an active area of research in [[astrophysics]] and particle physics, with scientists working to better understand its properties and role in the [[universe]].
==Additional Details==
1. Dark matter is estimated to make up approximately 85% of the total matter content in the [[universe]]. The remaining 15% is made up of visible matter, such as stars, [[planets]], and gas.
2. Dark matter is believed to be distributed throughout the universe in a "halo" around galaxies and other cosmic structures. It is thought to be most dense in the centers of galaxies and less dense in the outer regions.
3. The properties of dark matter particles are still unknown, but several candidates have been proposed, including [[Weakly Interacting Massive Particles (WIMPs)]], [[Axions]], and [[Sterile Neutrinos]].
4. The effects of dark matter can be observed through its gravitational lensing of light from distant galaxies and its influence on the rotation curves of galaxies.
5. Dark matter is distinct from [[dark energy]], which is a hypothetical form of energy that is believed to be responsible for the acceleration of the expansion of the universe. Dark energy is thought to make up approximately 70% of the total [[energy]] content of the universe.
6. The study of dark matter is important for understanding the large-scale structure of the universe, the formation and evolution of galaxies, and the fundamental nature of matter and the universe as a whole.
Despite decades of research, the nature of dark matter remains one of the biggest mysteries in astrophysics. Scientists continue to search for new ways to detect dark matter particles and better understand their properties and role in the universe.
e488c52821df618778bf1dc0b8cc1a920d0c8553
File:Dark-matter.jpg
6
190
423
2023-07-13T18:16:10Z
SpaceMan
2
wikitext
text/x-wiki
Image via RAS/ S. Epps & M. Hudson / University of Waterloo.
279cd8fe2cde6432ad14fa6c3b685d6d7be78d8e
File:Planet .jpg
6
191
426
2023-07-14T04:12:22Z
SpaceMan
2
wikitext
text/x-wiki
Credit: Wikipedia
e39e8e58ba05fc1af6dc2fb10cfb0de8592d098b
Planet
0
192
427
2023-07-14T04:13:43Z
SpaceMan
2
Created page with "A planet is a celestial body that orbits a [[star]] and is massive enough to form a nearly spherical shape under its own [[gravity]]. Planets are one of the most common types of objects in the [[universe]] and are typically composed of rock, metal, or gas. File:Planet .jpg|alt=Planets|center|frameless|The eight planets of the Solar System with size to scale (up to down, left to right): Saturn, Jupiter, Uranus, Neptune (outer planets), Earth, Venus, Mars, and Mercury (i..."
wikitext
text/x-wiki
A planet is a celestial body that orbits a [[star]] and is massive enough to form a nearly spherical shape under its own [[gravity]]. Planets are one of the most common types of objects in the [[universe]] and are typically composed of rock, metal, or gas.
[[File:Planet .jpg|alt=Planets|center|frameless|The eight planets of the Solar System with size to scale (up to down, left to right): Saturn, Jupiter, Uranus, Neptune (outer planets), Earth, Venus, Mars, and Mercury (inner planets). Credit: Wikipedia ]]
The study of planets is an active area of research in [[astronomy]] and planetary science, with scientists using a variety of techniques to study their properties and behavior. Here are some key features of planets:
1. Formation: Planets are thought to form from the protoplanetary disk of gas and dust that surrounds a young star. Over time, the material in the disk clumps together under the influence of gravity, eventually forming larger and larger objects that eventually become planets.
2. Composition: The composition of planets can vary depending on their distance from their parent star and the conditions in the protoplanetary disk. Terrestrial planets, such as [[Earth]] and [[Mars]], are primarily composed of rock and metal, while gas giants, such as [[Jupiter]] and [[Saturn]], are composed mostly of hydrogen and helium.
3. Atmospheres: Many planets have atmospheres, which are layers of gases that surround the planet. The composition and thickness of the atmosphere can vary depending on the planet's distance from its star and its size. Some planets, such as Earth, have atmospheres that are thick enough to support [[life]].
4. Moons: Many planets have one or more moons, which are [[natural satellites]] that orbit the planet. Moons can have a significant influence on the behavior of the planet, such as causing tides or affecting the planet's rotation.
5. Orbits: Planets orbit their parent star in elliptical orbits, with the period of the orbit depending on the distance from the star and the planet's mass. The study of planetary orbits is important for understanding the dynamics of the solar system and the formation of planets.
The study of planets is crucial for understanding the formation and evolution of the [[solar system]] and the potential for life beyond Earth. By studying planets in our own solar system and around other stars, [[astronomers]] and planetary scientists are able to gain a better understanding of the conditions necessary for the emergence and sustenance of life in the [[universe]].
[[Category:Astronomy]]
__FORCETOC__
__INDEX__
__NEWSECTIONLINK__
7efba2ae5c9f2a72ce630d73f43d8c9410533be3
Planets
0
193
428
2023-07-14T04:19:12Z
SpaceMan
2
Redirected page to [[Planet]]
wikitext
text/x-wiki
#REDIRECT [[Planet]]
__INDEX__
48ac313454b965b6eacfdcec5f0c4706b846ff9e